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

apimachinery: fix UnsafeGuessKindToResource for some classes of words #110053

Conversation

michaelbeaumont
Copy link
Contributor

What type of PR is this?

/kind bug

What this PR does / why we need it:

Fixes guesses that apimachinery makes about resource names from a GVK.

Which issue(s) this PR fixes:

Fixes kubernetes/client-go#1082

Special notes for your reviewer:

Does this PR introduce a user-facing change?

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. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 14, 2022
@k8s-ci-robot
Copy link
Contributor

Hi @michaelbeaumont. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@k8s-ci-robot k8s-ci-robot added needs-priority Indicates a PR lacks a `priority/foo` label and requires one. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels May 14, 2022
@k8s-ci-robot k8s-ci-robot requested review from deads2k and ncdc May 14, 2022 16:35
@roycaihw
Copy link
Member

/assign @apelisse
/triage accepted

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels May 17, 2022
@apelisse
Copy link
Member

/ok-to-test
/lgtm

Not sure if this breaks compatibility with anything.

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. lgtm "Looks good to me", indicates that a PR is ready to be merged. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 18, 2022
@AlexanderYastrebov
Copy link
Contributor

The https://github.com/kubernetes/code-generator uses https://pkg.go.dev/k8s.io/gengo/namer#NewAllLowercasePluralNamer so another option might be to use it here or make client-go use it instead of UnsafeGuessKindToResource that is documented as broken.

@evankanderson
Copy link

FWIW, this affects https://gateway-api.sigs.k8s.io/, which is sort of annoying (spent about 2-3 hours debugging why a test framework using .Add wasn't finding my Gateway).

👍 on this change from me.

@ncdc
Copy link
Member

ncdc commented Jul 13, 2022

/uncc

@k8s-ci-robot k8s-ci-robot removed the request for review from ncdc July 13, 2022 19:58
@evankanderson
Copy link

/assign @deads2k

@pmalek
Copy link
Contributor

pmalek commented Aug 9, 2022

Also hit this when using Gateway API's objects with dynamic fake client: k8s.io/client-go/dynamic/fake's NewSimpleDynamicClientWithCustomListKinds (just as @evankanderson described it).

Any (even rough) ETA for this? Any workarounds before this gets merged?

@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue or PR as fresh with /remove-lifecycle stale
  • Mark this issue or PR as rotten with /lifecycle rotten
  • Close this issue or PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Nov 7, 2022
@evankanderson
Copy link

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Nov 7, 2022
@pmalek
Copy link
Contributor

pmalek commented Nov 20, 2022

Any chance that we can get someone else to look at this and review it (as @deads2k and @apelisse seem not be able to pick this up)?

@apelisse
Copy link
Member

Why would you throw me under the bus? I've lgtm'd 6 months ago! 😄

@pmalek
Copy link
Contributor

pmalek commented Nov 22, 2022

@apelisse sorry 😅 Didn't notice that (and the fact that still @deads2k is assigned as reviewer: so I guess we need lgtm from him). My bad.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: michaelbeaumont, pmalek
Once this PR has been reviewed and has the lgtm label, please ask for approval from deads2k by writing /assign @deads2k in a comment. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found 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

@evankanderson
Copy link

/assign caesarxuchao

@lavalamp
Copy link
Member

I think we might have this code locked because changing it could break existing things and pluralizing english is hopeless unless we can call out to GPT-3 anyway.

There should be fields to define both in CRDs to avoid this code being invoked, if that's not the case please let us know.

@@ -137,10 +137,19 @@ func UnsafeGuessKindToResource(kind schema.GroupVersionKind) ( /*plural*/ schema
}
}

switch string(singularName[len(singularName)-1]) {
case "s":
switch {
Copy link
Member

@liggitt liggitt Dec 12, 2022

Choose a reason for hiding this comment

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

/hold

This isn't a compatible change to make to this function. Anything using this function to auto-generate plural names from singular names would break when re-generating an existing object that this change impacts.

I think we should remove all non-test in-tree calls to this function (I only see a single call from DefaultRESTMapper#Add, which I would also consider removing), mark it deprecated, file issues to public callers we find, and consider removing it in a future release.

If we want a new function that takes a singular name and pluralizes it that has this expanded behavior from the start (with a signature like AttemptToPluralize(singular string) (plural string)), I guess I wouldn't object, but that doesn't need to live in k8s.io/apimachinery

Copy link

Choose a reason for hiding this comment

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

I believe that the use that bit me was in test code without an apiserver loaded. I can try to dig out the code in question; I believe it tries to pluralize "Gateway" as "Gatewaies", which was very confusing when I finally debugged it.

Removing this function would also be acceptable to me, but it's currently a trap for anyone testing the Gateway API.

Copy link
Contributor

@pmalek pmalek Feb 12, 2023

Choose a reason for hiding this comment

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

@evankanderson Can you dig that test code up? I'm positive I've also encountered this issue recently but can't find the relevant test code that would manifest the problem itself (other than calling UnsafeGuessKindToResource with Gateway type).

https://grep.app/search?q=.UnsafeGuessKindToResource%28&case=true doesn't show that many public callers 👍

Copy link

Choose a reason for hiding this comment

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

I believe that we were getting hung up in tracker.Add from this code:

https://github.com/kubernetes/client-go/blob/master/testing/fixture.go#L341

I also see some questionable usage in https://github.com/knative/pkg/blob/main/resolver/addressable_resolver.go#L167 and https://github.com/knative/pkg/blob/main/kref/knative_reference.go#L53, but the usage of ObjectTracker from client-go/testing seems most likely to cause problems, because I'm guessing that package is used many places.

You can see my work-around here:

https://github.com/knative-sandbox/net-gateway-api/blob/main/pkg/reconciler/ingress/ingress_test.go#L404

		// The fake tracker's `Add` method incorrectly pluralizes "gatewaies" using UnsafeGuessKindToResource,
		// so create this via explicit call (per note in client-go/testing/fixture.go in tracker.Add)
		fakeCreates := []runtime.Object{}
		for _, x := range tr.Objects {
			myGw, ok := x.(*gatewayapi.Gateway)
			if ok {
				fakegwapiclientset.Get(ctx).GatewayV1beta1().Gateways(myGw.Namespace).Create(ctx, myGw, metav1.CreateOptions{})
				tr.SkipNamespaceValidation = true
				fakeCreates = append(fakeCreates, myGw)
			}
		}
		tr.WantCreates = append(fakeCreates, tr.WantCreates...)

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Dec 12, 2022
@liggitt
Copy link
Member

liggitt commented Mar 30, 2023

/close

Changing this function is not the right direction. I would be in favor of marking as deprecated and removing all in-tree calls to it, and adding the ability for fake clients to be told the accurate plural/singular mappings if needed.

@k8s-ci-robot
Copy link
Contributor

@liggitt: Closed this PR.

In response to this:

/close

Changing this function is not the right direction. I would be in favor of marking as deprecated and removing all in-tree calls to it, and adding the ability for fake clients to be told the accurate plural/singular mappings if needed.

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.

@pmalek
Copy link
Contributor

pmalek commented Jun 10, 2023

@liggitt I'd like to move forward with this somehow but I'm having hard time understanding your proposal.

E.g. how would you go about removing in-tree calls of this? There are multiple places where it's used in user facing code e.g.

func (m *DefaultRESTMapper) Add(kind schema.GroupVersionKind, scope RESTScope) {
plural, singular := UnsafeGuessKindToResource(kind)
m.AddSpecific(kind, plural, singular, scope)
}
func (m *DefaultRESTMapper) AddSpecific(kind schema.GroupVersionKind, plural, singular schema.GroupVersionResource, scope RESTScope) {
m.singularToPlural[singular] = plural
m.pluralToSingular[plural] = singular
m.resourceToKind[singular] = kind
m.resourceToKind[plural] = kind
m.kindToPluralResource[kind] = plural
m.kindToScope[kind] = scope
}

Would you suggest to mark func (m *DefaultRESTMapper) Add(kind schema.GroupVersionKind, scope RESTScope) as deprecated as well due to its usage of UnsafeGuessKindToResource and suggest users to use AddSpecific() instead?

@pmalek
Copy link
Contributor

pmalek commented Jun 10, 2023

It seems that using k8s.io/gengo/namer's NewAllLowercasePluralNamer() would work:

func (m *DefaultRESTMapper) Add(kind schema.GroupVersionKind, scope RESTScope) {
	n := namer.NewAllLowercasePluralNamer(nil)
	t := types.Ref(kind.GroupVersion().String(), kind.Kind)
	plural := kind.GroupVersion().WithResource(n.Name(t))
	singular := kind.GroupVersion().WithResource(strings.ToLower(kind.Kind))

	m.AddSpecific(kind, plural, singular, scope)
}

If this would be accepted and is perceived as the direction that we can move forward with, I can submit a PR replacing usages of UnsafeGuessKindToResource with the above.

@liggitt
Copy link
Member

liggitt commented Jul 5, 2023

Would you suggest to mark func (m *DefaultRESTMapper) Add(kind schema.GroupVersionKind, scope RESTScope) as deprecated as well due to its usage of UnsafeGuessKindToResource and suggest users to use AddSpecific() instead?

yes, mark deprecated and mark callers that rely on it as deprecated as well, pointing people to AddSpecific

@pmalek
Copy link
Contributor

pmalek commented Aug 13, 2023

@liggitt I've pushed #119924 to try to address the above PTAL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. 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. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pluralization discrepancy in UnsafeGuessKindToResource still exists