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

update fake dynamic client to return GVK #96020

Merged
merged 4 commits into from Nov 5, 2020

Conversation

deads2k
Copy link
Contributor

@deads2k deads2k commented Oct 29, 2020

Thanks to @andrewsykim for #95951, the test he added to make this obvious, and the action wiring itself.

I created a proof commit to show that generated clients do not return GVK for from their serialized bytes. Whether this is right or wrong is a problem for another day. In comparison, the dynamic client does return GVK information so that it can be interpreted by other layers. The fake dynamic client did not do this.

This PR keeps the fake generated clients as they are, loads a GVR to listGVK mapping in the dynamic client by doing an unsafe guess, and allows for overrides of specific resources to specific list GVK mappings. It also adds several panics to catch test behavior that needs updating (coding errors).

/kind bug
@kubernetes/sig-api-machinery-bugs
/assign @andrewsykim
/priority important-soon

NONE

andrewsykim and others added 2 commits October 29, 2020 15:55
Today the dynamic fake client is not aware of *List kinds, so List calls return UnstructuredList
objects without TypeMeta. This patch updates client-go's fake object tracker to store a map of
GVR to list GVKs. In this way, the list GVK can be set for UnstructuredList objects.

Signed-off-by: Andrew Sy Kim <kim.andrewsy@gmail.com>
@k8s-ci-robot k8s-ci-robot added sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. kind/bug Categorizes issue or PR as related to a bug. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. area/kubectl sig/cli Categorizes an issue or PR as relevant to SIG CLI. labels Oct 29, 2020
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: deads2k

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 Oct 29, 2020
@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Oct 29, 2020
@roycaihw
Copy link
Member

/assign @yliaog
/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 Oct 29, 2020
return NewSimpleDynamicClientWithCustomResourceMapping(scheme, nil, objects...)
}

// NewSimpleDynamicClientWithCustomResourceMapping try not o use this. In general you want to have the scheme have the List types registered
Copy link
Contributor

Choose a reason for hiding this comment

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

typo, try no o use -> try not to use

@@ -799,7 +810,7 @@ func TestWaitForDeletionIgnoreNotFound(t *testing.T) {
Namespace: "ns-foo",
},
}
fakeClient := dynamicfakeclient.NewSimpleDynamicClient(scheme)
fakeClient := dynamicfakeclient.NewSimpleDynamicClientWithCustomResourceMapping(scheme, listMapping)

Copy link
Contributor

Choose a reason for hiding this comment

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

is this necessary? could you keep using NewSimpleDynamicClient(scheme) here and in other call sites above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is this necessary? could you keep using NewSimpleDynamicClient(scheme) here and in other call sites above?

I can't because the existing tests separate resources and versions with unguessable names. I have to provide the mapping somehow and schemes don't allow it. I'm not sure how many other locations will face the same issue. Plurals in english are weird (and that's just english), so I think this is needed to provide people a path to upgrade.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok. the other way is to make it always guessable, which means changing the guess function if/when necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok. the other way is to make it always guessable, which means changing the guess function if/when necessary.

external components (imagine you have a custom operator) cannot modify that code.

return NewSimpleDynamicClientWithCustomResourceMapping(scheme, nil, objects...)
}

// NewSimpleDynamicClientWithCustomResourceMapping try not o use this. In general you want to have the scheme have the List types registered
Copy link
Member

Choose a reason for hiding this comment

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

nit: s/o/to


// NewSimpleDynamicClientWithCustomResourceMapping try not o use this. In general you want to have the scheme have the List types registered
// and allow the default guessing for resources match. Sometimes that doesn't work, so you can specify a custom mapping here.
func NewSimpleDynamicClientWithCustomResourceMapping(scheme *runtime.Scheme, gvrToListKind map[schema.GroupVersionResource]string, objects ...runtime.Object) *FakeDynamicClient {
Copy link
Member

Choose a reason for hiding this comment

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

Would it be helpful to be explicit about List kinds and name this NewSimpleDynamicClientWithCustomListKinds

if cm.GetObjectKind().GroupVersionKind() != (schema.GroupVersionKind{}) {
t.Fatal(cm.GetObjectKind().GroupVersionKind())
}
cmList, err := fakeKubeClient.CoreV1().ConfigMaps("foo-ns").Get(context.TODO(), "foo-name", metav1.GetOptions{})
Copy link
Member

Choose a reason for hiding this comment

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

I'm guessing this is supposed to call List and not Get

t.Fatal(err)
}
if cmList.GetObjectKind().GroupVersionKind() != (schema.GroupVersionKind{}) {
t.Fatal(cm.GetObjectKind().GroupVersionKind())
Copy link
Contributor

Choose a reason for hiding this comment

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

s/cm/cmList/

@@ -799,7 +810,7 @@ func TestWaitForDeletionIgnoreNotFound(t *testing.T) {
Namespace: "ns-foo",
},
}
fakeClient := dynamicfakeclient.NewSimpleDynamicClient(scheme)
fakeClient := dynamicfakeclient.NewSimpleDynamicClientWithCustomResourceMapping(scheme, listMapping)

Copy link
Contributor

Choose a reason for hiding this comment

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

ok. the other way is to make it always guessable, which means changing the guess function if/when necessary.

@deads2k
Copy link
Contributor Author

deads2k commented Nov 2, 2020

ok. the other way is to make it always guessable, which means changing the guess function if/when necessary.

In usage, if your resource has a plural that isn't guessable, then you couldn't use this client to test your actual resource. Imagine writing controllers that use dynamic clients to access oxen or some such.

Copy link
Contributor

@yliaog yliaog left a comment

Choose a reason for hiding this comment

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

i was thinking about making the guess function extendable for such non-guessable cases. but no matter your current way or the other way, there must be a way to provide a mapping of non-guessable Kind -> list Kind. i'm fine with the current way. thanks.

"k8s.io/client-go/kubernetes/scheme"
)

// this test proves that the kube fake client does not return GVKs
Copy link
Contributor

Choose a reason for hiding this comment

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

add a TODO comment, so readers know this is not desired, and should be fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

add a TODO comment, so readers know this is not desired, and should be fixed?

sure. I will clarify.

t.Fatal(cm.GetObjectKind().GroupVersionKind())
}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

the following two tests are not about fake client, should the file name be renamed to something other than fake_client_test.go?

gvrToListKind := map[schema.GroupVersionResource]string{
{Group: "apps", Version: "v1", Resource: "deployments"}: "DeploymentList",
}
fakeClient := fake.NewSimpleDynamicClientWithCustomResourceMapping(scheme, gvrToListKind, objs...)
Copy link
Contributor

Choose a reason for hiding this comment

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

sorry, i'm a bit confused. 'deployments' -> 'DeploymentList' should be guessable, no? is the switch from NewSimpleDynamicClient to NewSimpleDynamicClientWithCustomResourceMapping here really necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry, i'm a bit confused. 'deployments' -> 'DeploymentList' should be guessable, no? is the switch from NewSimpleDynamicClient to NewSimpleDynamicClientWithCustomResourceMapping here really necessary?

The scheme they choose to test with does not have the deployment listed. This test is specifically about whether dynamic resources (those without scheme entries) can be properly handled. This means that it is correct for the usage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

clarifying in comments.

@deads2k
Copy link
Contributor Author

deads2k commented Nov 4, 2020

updated for comments and verify. Clarified several points in the code.

@andrewsykim
Copy link
Member

I think it would be useful to include release notes for this bug fix. Not familiar enough with apimachinery to lgtm this so I'll defer that to someone else who is.

@yliaog
Copy link
Contributor

yliaog commented Nov 4, 2020

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 4, 2020
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@k8s-ci-robot k8s-ci-robot merged commit dbd2be0 into kubernetes:master Nov 5, 2020
@k8s-ci-robot k8s-ci-robot added this to the v1.20 milestone Nov 5, 2020
@andrewsykim
Copy link
Member

@deads2k can we cherry-pick this?

@deads2k
Copy link
Contributor Author

deads2k commented Nov 5, 2020

@deads2k can we cherry-pick this?

I'll go back to 1.19 if you like #96268 . The issue and original just missed that. I don't think it's really worth it to go further.

@andrewsykim
Copy link
Member

Thanks @deads2k!

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/kubectl 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. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. 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. sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/L Denotes a PR that changes 100-499 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.

None yet

6 participants