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

instancetype: Reject Matcher updates without updating RevisionName #9421

Merged
merged 1 commit into from
Mar 23, 2023

Conversation

lyarwood
Copy link
Member

@lyarwood lyarwood commented Mar 13, 2023

/area instancetype

What this PR does / why we need it:

As set out in issue #9132 requests to update the Name of an {Instancetype,Preference}Matcher were always accepted regardless of the RevisionName also being updated. This would result in an older and likely unwanted ControllerRevision being used containing an outdated or completely wrong Instancetype or Preference.

With this change the VM mutation webhook will now reject requests to update the target Name of a {Instancetype,Preference}Matcher without also updating the RevisionName.

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 #9132

Special notes for your reviewer:

Release note:

 Requests to update the target `Name` of a `{Instancetype,Preference}Matcher` without also updating the `RevisionName` are now rejected.

@kubevirt-bot kubevirt-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. area/instancetype dco-signoff: yes Indicates the PR's author has DCO signed all their commits. labels Mar 13, 2023
@kubevirt-bot kubevirt-bot added kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API size/L labels Mar 13, 2023
Comment on lines 278 to 282
if oldMatcher.GetName() != newMatcher.GetName() && newMatcher.GetRevisionName() != "" {
return fmt.Errorf("the Matcher Name has been updated without clearing the RevisionName")
}
Copy link
Member

Choose a reason for hiding this comment

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

Change this to

		if oldMatcher.GetName() != newMatcher.GetName() && oldMatcher.GetRevisionName() == newMatcher.GetRevisionName() {
			return fmt.Errorf("the Matcher Name has been updated without updating the RevisionName")
		}

to allow changing to a different matcher with a specific revision in one go?

@lyarwood
Copy link
Member Author

/retest-required

Copy link
Member

@0xFelix 0xFelix left a comment

Choose a reason for hiding this comment

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

/lgtm

Thanks!

@kubevirt-bot kubevirt-bot added the lgtm Indicates that a PR is ready to be merged. label Mar 15, 2023
@lyarwood lyarwood changed the title instancetype: Reject Matcher updates without clearing RevisionName instancetype: Reject Matcher updates without updating RevisionName Mar 16, 2023
@lyarwood
Copy link
Member Author

/cherrypick release-0.59

@kubevirt-bot
Copy link
Contributor

@lyarwood: once the present PR merges, I will cherry-pick it on top of release-0.59 in a new PR and assign it to you.

In response to this:

/cherrypick release-0.59

Instructions 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/test-infra repository.

return nil
}

func validateMatcherUpdate[M v1.Matcher](oldMatcher M, newMatcher M) error {
Copy link
Member

Choose a reason for hiding this comment

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

Why generic?

Copy link
Member Author

Choose a reason for hiding this comment

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

To save duplicating the logic below between {Instancetype,Preference}Matcher.

Copy link
Member

Choose a reason for hiding this comment

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

func validateMatcherUpdate(oldMatcher, newMatcher v1.Matcher) error works fine. Can you elaborate?

Copy link
Member Author

Choose a reason for hiding this comment

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

@xpivarc hopefully that answered your question, would you mind taking another look?

Copy link
Member Author

Choose a reason for hiding this comment

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

func validateMatcherUpdate(oldMatcher, newMatcher v1.Matcher) error works fine. Can you elaborate?

facepalm I'll drop this now sorry.

@@ -125,6 +147,7 @@ var _ = Describe("VirtualMachine Mutator", func() {

k8sClient = k8sfake.NewSimpleClientset()
virtClient.EXPECT().CoreV1().Return(k8sClient.CoreV1()).AnyTimes()
virtClient.EXPECT().AppsV1().Return(k8sClient.AppsV1()).AnyTimes()
Copy link
Member

Choose a reason for hiding this comment

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

Why is this required?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question, the mutation webhook will attempt to lookup any preference related ControllerRevisions but ultimately swallow any errors later in the mutation flow:

preferenceSpec, err := mutator.InstancetypeMethods.FindPreferenceSpec(vm)
if err != nil {
// Log but ultimately swallow any preference lookup errors here and let the validating webhook handle them
log.Log.Reason(err).Error("Ignoring error attempting to lookup PreferredMachineType.")
return nil
}

Copy link
Member

Choose a reason for hiding this comment

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

But it is required for the introduced context and not for this one. So can we move it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup that's true, I'll move it down.

Copy link
Member

@xpivarc xpivarc left a comment

Choose a reason for hiding this comment

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

Sorry I forgot to submit my review

return nil
}

func validateMatcherUpdate[M v1.Matcher](oldMatcher M, newMatcher M) error {
Copy link
Member

Choose a reason for hiding this comment

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

func validateMatcherUpdate(oldMatcher, newMatcher v1.Matcher) error works fine. Can you elaborate?

@@ -125,6 +147,7 @@ var _ = Describe("VirtualMachine Mutator", func() {

k8sClient = k8sfake.NewSimpleClientset()
virtClient.EXPECT().CoreV1().Return(k8sClient.CoreV1()).AnyTimes()
virtClient.EXPECT().AppsV1().Return(k8sClient.AppsV1()).AnyTimes()
Copy link
Member

Choose a reason for hiding this comment

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

But it is required for the introduced context and not for this one. So can we move it?

@kubevirt-bot kubevirt-bot removed the lgtm Indicates that a PR is ready to be merged. label Mar 21, 2023
Copy link
Member

@xpivarc xpivarc left a comment

Choose a reason for hiding this comment

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

/approve
@0xFelix Can you give this one proper look?

@kubevirt-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: xpivarc

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

@kubevirt-bot kubevirt-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 21, 2023
if oldPreferenceMatcher == nil && newPreferenceMatcher == nil {
return nil
}
if err := validateMatcherUpdate(*oldPreferenceMatcher, *newPreferenceMatcher); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Can you pass the matchers without derefing them?

Copy link
Member Author

@lyarwood lyarwood Mar 21, 2023

Choose a reason for hiding this comment

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

edit - Apologies replied to the wrong comment, staticcheck was complaining about something before when I tried this but it's working now. Updated.

}

func validatePreferenceMatcherUpdate(oldPreferenceMatcher *v1.PreferenceMatcher, newPreferenceMatcher *v1.PreferenceMatcher) []metav1.StatusCause {
if oldPreferenceMatcher == nil && newPreferenceMatcher == nil {
Copy link
Member

Choose a reason for hiding this comment

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

What happens if only one matcher is nil? Will it panic?

Copy link
Member Author

@lyarwood lyarwood Mar 21, 2023

Choose a reason for hiding this comment

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

Yeah good catch, updated the && above, should be || to skip the check when one side isn't provided when they are initially introduced or later dropped.

As set out in issue kubevirt#9132 requests to update the Name of an
{Instancetype,Preference}Matcher were always accepted regardless of the
RevisionName being cleared or updated. This would result in an older and
likely unwanted ControllerRevision being used containing an outdated or
completely wrong Instancetype or Preference.

With this change the VM mutation webhook will now reject requests to
update the target Name of a {Instancetype,Preference}Matcher without
also clearing or updating the RevisionName.

Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
@0xFelix
Copy link
Member

0xFelix commented Mar 22, 2023

Thanks!

/lgtm
/retest

@kubevirt-bot kubevirt-bot added the lgtm Indicates that a PR is ready to be merged. label Mar 22, 2023
@kubevirt-bot
Copy link
Contributor

kubevirt-bot commented Mar 22, 2023

@lyarwood: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-kubevirt-fossa 0bad7c2 link false /test pull-kubevirt-fossa

Instructions 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/test-infra repository. I understand the commands that are listed here.

@lyarwood
Copy link
Member Author

/retest-required

@kubevirt-commenter-bot
Copy link

/retest-required
This bot automatically retries required jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

1 similar comment
@kubevirt-commenter-bot
Copy link

/retest-required
This bot automatically retries required jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-bot
Copy link
Contributor

@lyarwood: new pull request created: #9500

In response to this:

/cherrypick release-0.59

Instructions 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/test-infra repository.

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. area/instancetype dco-signoff: yes Indicates the PR's author has DCO signed all their commits. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L
Projects
None yet
5 participants