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

✨ Add TransformStripManagedFields #2791

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions pkg/cache/cache.go
Expand Up @@ -201,6 +201,9 @@ type Options struct {

// DefaultTransform will be used as transform for all object types
// unless there is already one set in ByObject or DefaultNamespaces.
//
// A typical usecase for this is to use TransformStripManagedFields
// to reduce the caches memory usage.
DefaultTransform toolscache.TransformFunc

// DefaultWatchErrorHandler will be used to the WatchErrorHandler which is called
Expand Down Expand Up @@ -344,6 +347,20 @@ func New(cfg *rest.Config, opts Options) (Cache, error) {
return delegating, nil
}

// TransformStripManagedFields strips the managed fields of an object before it is committed to the cache.
// If you are not explicitly accessing managedFields from your code, setting this as `DefaultTransform`
// on the cache can lead to a significant reduction in memory usage.
func TransformStripManagedFields() toolscache.TransformFunc {
return func(in any) (any, error) {
// Nilcheck managed fields to avoid hitting https://github.com/kubernetes/kubernetes/issues/124337
if obj, err := meta.Accessor(in); err == nil && obj.GetManagedFields() != nil {
obj.SetManagedFields(nil)
}

return in, nil
}
}

func optionDefaultsToConfig(opts *Options) Config {
return Config{
LabelSelector: opts.DefaultLabelSelector,
Expand Down
19 changes: 19 additions & 0 deletions pkg/cache/cache_test.go
Expand Up @@ -2421,6 +2421,25 @@ func CacheTest(createCacheFunc func(config *rest.Config, opts cache.Options) (ca
})
}

var _ = Describe("TransformStripManagedFields", func() {
It("should strip managed fields from an object", func() {
obj := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{
ManagedFields: []metav1.ManagedFieldsEntry{{
Manager: "foo",
}},
}}
transformed, err := cache.TransformStripManagedFields()(obj)
Expect(err).NotTo(HaveOccurred())
Expect(transformed).To(Equal(&corev1.Pod{ObjectMeta: metav1.ObjectMeta{}}))
})

It("should not trip over an unexpected object", func() {
transformed, err := cache.TransformStripManagedFields()("foo")
Expect(err).NotTo(HaveOccurred())
Expect(transformed).To(Equal("foo"))
})
})

// ensureNamespace installs namespace of a given name if not exists.
func ensureNamespace(namespace string, client client.Client) error {
ns := corev1.Namespace{
Expand Down