Skip to content
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

fix tag delete following resource create #3187

Merged
merged 1 commit into from
Feb 28, 2023

Conversation

nojnhuh
Copy link
Contributor

@nojnhuh nojnhuh commented Feb 17, 2023

What type of PR is this?
/kind bug

What this PR does / why we need it: Fixes an issue where deleting any values from an AzureCluster's or AzureManagedCluster's spec.additionalTags before making any other changes to that field never takes effect on the Azure resource group because the last-applied-tags annotation is not applied initially. This change ensures the annotation is set on each reconciliation loop, whether or not the tags need to be updated.

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #3185

Special notes for your reviewer:

Please confirm that if this PR changes any image versions, then that's the sole change this PR makes.

TODOs:

  • squashed commits
  • includes documentation
  • adds unit tests

Release note:

NONE

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/bug Categorizes issue or PR as related to a bug. labels Feb 17, 2023
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Feb 17, 2023
Copy link
Contributor

@willie-yao willie-yao left a comment

Choose a reason for hiding this comment

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

This looks great! Just one comment: Is there a way to add a test case in TestReconcileTags for ensuring the annotations are updated even when the tags aren't changed?

Comment on lines +110 to +115

// We also need to update the annotation even if nothing changed to
// ensure it's set immediately following resource creation.
if err := s.Scope.UpdateAnnotationJSON(tagsSpec.Annotation, newAnnotation); err != nil {
return err
}
Copy link
Member

Choose a reason for hiding this comment

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

Will this change lead to a new reconciliation for every tag from the for loop up above (as the resource version gets updated on annotation update) ?
If yes, could such a change create throttling situation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This UpdateAnnotationJSON method doesn't make any API calls, it only sets the annotation on the corresponding CAPZ resource like this:

// UpdateAnnotationJSON updates the `annotation` with
// `content`. `content` in this case should be a `map[string]interface{}`
// suitable for turning into JSON. This `content` map will be marshalled into a
// JSON string before being set as the given `annotation`.
func (s *ClusterScope) UpdateAnnotationJSON(annotation string, content map[string]interface{}) error {
b, err := json.Marshal(content)
if err != nil {
return err
}
s.SetAnnotation(annotation, string(b))
return nil
}
// SetAnnotation sets a key value annotation on the AzureCluster.
func (s *ClusterScope) SetAnnotation(key, value string) {
if s.AzureCluster.Annotations == nil {
s.AzureCluster.Annotations = map[string]string{}
}
s.AzureCluster.Annotations[key] = value
}

Then at the very end of the AzureCluster-level Reconcile, that resource is committed to the API with all of the changes made in that reconciliation, so different iterations of this for loop would be coalesced into a single Kubernetes API update. I think this change in particular will only introduce at most one additional reconciliation during the lifetime of the resource which adds the annotation the first time.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for pinning cluster-api-provider-azure/azure/scope/cluster.go lines above, helps to put things in perspective.
Following the code flow from the perspective of generating additional reconciliations, I do not see any Patch/Update/return reconcile:true calls on updating annotations or in function s.Scope.UpdateAnnotationJSON().

So looks good to me!

@nojnhuh
Copy link
Contributor Author

nojnhuh commented Feb 22, 2023

This looks great! Just one comment: Is there a way to add a test case in TestReconcileTags for ensuring the annotations are updated even when the tags aren't changed?

@willie-yao Yes, this does include an update to the "tags unchanged" test case.

Copy link
Contributor

@willie-yao willie-yao left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 22, 2023
@k8s-ci-robot
Copy link
Contributor

LGTM label has been added.

Git tree hash: a2e6819f015e1d014a6f43f0ddfd45900cbb7598


// We also need to update the annotation even if nothing changed to
// ensure it's set immediately following resource creation.
if err := s.Scope.UpdateAnnotationJSON(tagsSpec.Annotation, newAnnotation); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of updating it every time, would it make sense (and be possible) to only set it the first time we go through here and the annotation doesn't exist? otherwise we're updating the annotation every time even if nothing changed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When nothing changes, doesn't this basically turn into a no-op? A patch is still unconditionally applied at the end of the reconciliation loop whether or not anything in the AzureCluster, etc. changes, so I don't think this would generate any additional ongoing API overhead. That being said, it would be simple to wrap this in something like a if tagsSpec.Annotation != newAnnotation block.

Copy link
Contributor

Choose a reason for hiding this comment

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

fair

@nawazkh
Copy link
Member

nawazkh commented Feb 27, 2023

/lgtm

@CecileRobertMichon
Copy link
Contributor

/lgtm
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: CecileRobertMichon

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 27, 2023
@k8s-ci-robot k8s-ci-robot merged commit 7bc81c1 into kubernetes-sigs:main Feb 28, 2023
@k8s-ci-robot k8s-ci-robot added this to the v1.8 milestone Feb 28, 2023
@jackfrancis jackfrancis mentioned this pull request Feb 28, 2023
3 tasks
@nojnhuh nojnhuh deleted the fix-tag-delete branch February 28, 2023 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deleting from spec.additionalTags following create does not take effect
5 participants