Skip to content

✨ Fakeclient: Add apply support #2981

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

Merged
merged 1 commit into from
Jun 26, 2025

Conversation

alvaroaleman
Copy link
Member

@alvaroaleman alvaroaleman commented Oct 14, 2024

This change adds apply support into the fake client.

This relies on the upstream support for this which is implemented in a new FieldManagedObjectTracker. In order to support many types, a custom multiTypeConverter is added.

The FieldManagedObjectTracker results in ManagedFields being set after any operations. As that would be a very breaking change, the fake client will by default unset them and allows to optionally leave them.

Based on all existing tests still passing, I believe this change is fully backwards-compatible (But depends on breaking changes such as a very new client-go and apimachinery and #3228).

Fixes #2341

@k8s-ci-robot
Copy link
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. 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. labels Oct 14, 2024
@k8s-ci-robot k8s-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Oct 14, 2024
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 10, 2024
@k8s-triage-robot
Copy link

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

This bot triages 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 PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle stale
  • Close this 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 Feb 8, 2025
@alvaroaleman
Copy link
Member Author

/lifecycle frozen
This is a requested feature so I'd like to keep this open to demonstrate the challenges. I personally will not be working further on it though.

@k8s-ci-robot
Copy link
Contributor

@alvaroaleman: The lifecycle/frozen label cannot be applied to Pull Requests.

In response to this:

/lifecycle frozen
This is a requested feature so I'd like to keep this open to demonstrate the challenges. I personally will not be working further on it though.

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-sigs/prow repository.

@alvaroaleman alvaroaleman added the lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. label Feb 8, 2025
@k8s-triage-robot
Copy link

The lifecycle/frozen label can not be applied to PRs.

This bot removes lifecycle/frozen from PRs because:

  • Commenting /lifecycle frozen on a PR has not worked since March 2021
  • PRs that remain open for >150 days are unlikely to be easily rebased

You can:

  • Rebase this PR and attempt to get it merged
  • Close this PR with /close

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

/remove-lifecycle frozen

@k8s-ci-robot k8s-ci-robot removed the lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. label Feb 9, 2025
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 23, 2025
@alvaroaleman alvaroaleman changed the title ✨ Fakeclient: Add apply support ⚠️ : Fakeclient: Add apply support Feb 23, 2025
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Feb 23, 2025
@alvaroaleman alvaroaleman changed the title ⚠️ : Fakeclient: Add apply support ⚠️ Fakeclient: Add apply support Feb 23, 2025
Comment on lines +28 to +30
type multiTypeConverter struct {
upstream []managedfields.TypeConverter
}
Copy link

Choose a reason for hiding this comment

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

Providing this composite type converter seems fine.

We have a different use case for a composite type converter in the apiserver for admission: https://github.com/kubernetes/kubernetes/blob/25e11cd1c143ef136418c33bfbbbd4f24e32e529/staging/src/k8s.io/apiserver/pkg/admission/plugin/policy/mutating/patch/typeconverter.go#L37. But the use case is different, it takes a single static type converter and an openapi client, instead of multiple underlying type converters, so it is not useful here.

I'd like to ensure we keep this implementation unexported. Maybe add some godoc to that effect?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep makes sense, will do that

@@ -119,6 +123,7 @@ type ClientBuilder struct {
withStatusSubresource []client.Object
objectTracker testing.ObjectTracker
interceptorFuncs *interceptor.Funcs
typeConverters []managedfields.TypeConverter
Copy link

@jpbetz jpbetz Feb 25, 2025

Choose a reason for hiding this comment

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

nit: Can this simply be typeConverter managedfields.TypeConverter? When multiTypeConverter is needed, it should implement the managedfields.TypeConverter interface and so can be initialized and used here?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is on the builder and often times it will be needed to have more than one, as both in-tree and CRs are used

Copy link

@jpbetz jpbetz 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 like a good approach. Left some minor feedback then LGTM.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 8, 2025
@sbueringer sbueringer mentioned this pull request Mar 30, 2025
9 tasks
@k8s-triage-robot
Copy link

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

This bot triages 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 PR is closed

You can:

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

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

/lifecycle rotten

@alvaroaleman alvaroaleman changed the title ⚠️ Fakeclient: Add apply support ✨ Fakeclient: Add apply support Jun 6, 2025
@alvaroaleman alvaroaleman removed the lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. label Jun 6, 2025
@alvaroaleman alvaroaleman force-pushed the apply-fake branch 3 times, most recently from d6585af to e087e01 Compare June 7, 2025 20:25
@tomasaschan

This comment was marked as off-topic.

@fsommar

This comment was marked as off-topic.

@tomasaschan

This comment was marked as off-topic.

@@ -228,6 +237,29 @@ func (f *ClientBuilder) WithInterceptorFuncs(interceptorFuncs interceptor.Funcs)
return f
}

// WithTypeConverters sets the type converters for the fake client. The list is ordered and the first
// non-erroring converter is used. A type converter must be provided for all types the client is used
Copy link
Member

@sbueringer sbueringer Jun 19, 2025

Choose a reason for hiding this comment

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

Under which exact circumstances must these be provided?

Only if SSA with custom types is used with the fake client? (based on the unit test it looks like Unstructured also works without setting TypeConverters)

Copy link
Member Author

Choose a reason for hiding this comment

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

It is always requiered if the FieldManagedObjectTracker is used, it seems to error out on all of its methods if the typeConverter doesn't handle a given type

Copy link
Member

@sbueringer sbueringer Jun 19, 2025

Choose a reason for hiding this comment

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

I think I'm missing something.

So if I'm using the fake client today with my own CRDs, this will now break if I don't start setting type converters for them? This would break a lot of people

(FieldManagedObjectTracker is always used if objectTracker is not explicitly set, right?)

Copy link
Member Author

Choose a reason for hiding this comment

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

So if I'm using the fake client today with my own CRDs, this will now break if I don't start setting type converters for them? This would break a lot of people

No it will not break. SSA might not work correctly due to the inferencing type converter, but that is all.

Copy link
Member

@sbueringer sbueringer Jun 26, 2025

Choose a reason for hiding this comment

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

Okay, can we make this slightly clearer please? The current comment is

A type converter must be provided for all types the client is used for, otherwise it will error.

I'm not sure if folks will infer that correctly otherwise

@sbueringer
Copy link
Member

sbueringer commented Jun 19, 2025

Nice! Thx for working on this.

My comments are mostly around improving test coverage and godoc a bit

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 19, 2025
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 19, 2025
@alvaroaleman
Copy link
Member Author

alvaroaleman commented Jun 19, 2025

@tomasaschan @fsommar could you please find a different place for your comments that are not about feedback to the code changes in here to avoid polluting this? Thanks!

@alvaroaleman alvaroaleman force-pushed the apply-fake branch 3 times, most recently from c33ac89 to 04c0089 Compare June 20, 2025 17:36
@sbueringer
Copy link
Member

@alvaroaleman Last one from my side: #2981 (comment)

@alvaroaleman alvaroaleman force-pushed the apply-fake branch 2 times, most recently from b83e359 to 2f94e55 Compare June 26, 2025 16:54
This change adds apply support into the fake client.

This relies on the upstream support for this which is implemented in a
new [FieldManagedObjectTracker][0]. In order to support many types, a
custom `multiTypeConverter` is added.

[0]: https://github.com/kubernetes/kubernetes/blob/4dc7a48ac6fb631a84e1974772bf7b8fd0bb9c59/staging/src/k8s.io/client-go/testing/fixture.go#L643
@sbueringer
Copy link
Member

/lgtm
/approve

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

LGTM label has been added.

Git tree hash: 2b9d7c67fa6bf77671bde55014a360b49b49e0fd

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alvaroaleman, sbueringer

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:
  • OWNERS [alvaroaleman,sbueringer]

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 merged commit cacd627 into kubernetes-sigs:main Jun 26, 2025
9 checks passed
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. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support server-side apply (client.Apply) in fake Client
7 participants