Skip to content

Commit 2bc17d1

Browse files
committed
Add ResetFieldsFilterStrategy
1 parent 6fe5140 commit 2bc17d1

File tree

5 files changed

+45
-18
lines changed

5 files changed

+45
-18
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ func scopeWithFieldManager(typeConverter managedfields.TypeConverter, reqScope h
10721072
reqScope.Kind,
10731073
reqScope.HubGroupVersion,
10741074
subresource,
1075-
resetFields,
1075+
fieldpath.NewExcludeFilterSetMap(resetFields),
10761076
)
10771077
if err != nil {
10781078
return handlers.RequestScope{}, err

staging/src/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ package managedfields
1919
import (
2020
"fmt"
2121

22+
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
23+
2224
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2325
"k8s.io/apimachinery/pkg/runtime"
2426
"k8s.io/apimachinery/pkg/runtime/schema"
2527
"k8s.io/apimachinery/pkg/util/managedfields/internal"
26-
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
2728
)
2829

2930
// FieldManager updates the managed fields and merges applied
@@ -32,7 +33,7 @@ type FieldManager = internal.FieldManager
3233

3334
// NewDefaultFieldManager creates a new FieldManager that merges apply requests
3435
// and update managed fields for other types of requests.
35-
func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (*FieldManager, error) {
36+
func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (*FieldManager, error) {
3637
f, err := internal.NewStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields)
3738
if err != nil {
3839
return nil, fmt.Errorf("failed to create field manager: %v", err)
@@ -43,7 +44,7 @@ func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime
4344
// NewDefaultCRDFieldManager creates a new FieldManager specifically for
4445
// CRDs. This allows for the possibility of fields which are not defined
4546
// in models, as well as having no models defined at all.
46-
func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (_ *FieldManager, err error) {
47+
func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (_ *FieldManager, err error) {
4748
f, err := internal.NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields)
4849
if err != nil {
4950
return nil, fmt.Errorf("failed to create field manager: %v", err)

staging/src/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ package internal
1919
import (
2020
"fmt"
2121

22+
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
23+
"sigs.k8s.io/structured-merge-diff/v4/merge"
24+
"sigs.k8s.io/structured-merge-diff/v4/typed"
25+
2226
"k8s.io/apimachinery/pkg/api/errors"
2327
"k8s.io/apimachinery/pkg/api/meta"
2428
"k8s.io/apimachinery/pkg/runtime"
2529
"k8s.io/apimachinery/pkg/runtime/schema"
26-
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
27-
"sigs.k8s.io/structured-merge-diff/v4/merge"
28-
"sigs.k8s.io/structured-merge-diff/v4/typed"
2930
)
3031

3132
type structuredMergeManager struct {
@@ -41,7 +42,7 @@ var _ Manager = &structuredMergeManager{}
4142

4243
// NewStructuredMergeManager creates a new Manager that merges apply requests
4344
// and update managed fields for other types of requests.
44-
func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (Manager, error) {
45+
func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (Manager, error) {
4546
if typeConverter == nil {
4647
return nil, fmt.Errorf("typeconverter must not be nil")
4748
}
@@ -52,25 +53,25 @@ func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runt
5253
groupVersion: gv,
5354
hubVersion: hub,
5455
updater: merge.Updater{
55-
Converter: newVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s
56-
IgnoredFields: resetFields,
56+
Converter: newVersionConverter(typeConverter, objectConverter, hub), // This is the converter provided to SMD from k8s
57+
IgnoreFilter: resetFields,
5758
},
5859
}, nil
5960
}
6061

6162
// NewCRDStructuredMergeManager creates a new Manager specifically for
6263
// CRDs. This allows for the possibility of fields which are not defined
6364
// in models, as well as having no models defined at all.
64-
func NewCRDStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (_ Manager, err error) {
65+
func NewCRDStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]fieldpath.Filter) (_ Manager, err error) {
6566
return &structuredMergeManager{
6667
typeConverter: typeConverter,
6768
objectConverter: objectConverter,
6869
objectDefaulter: objectDefaulter,
6970
groupVersion: gv,
7071
hubVersion: hub,
7172
updater: merge.Updater{
72-
Converter: newCRDVersionConverter(typeConverter, objectConverter, hub),
73-
IgnoredFields: resetFields,
73+
Converter: newCRDVersionConverter(typeConverter, objectConverter, hub),
74+
IgnoreFilter: resetFields,
7475
},
7576
}, nil
7677
}

staging/src/k8s.io/apiserver/pkg/endpoints/installer.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,27 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
685685
reqScope.MetaGroupVersion = *a.group.MetaGroupVersion
686686
}
687687

688-
var resetFields map[fieldpath.APIVersion]*fieldpath.Set
689-
if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy {
690-
resetFields = resetFieldsStrategy.GetResetFields()
688+
// Strategies may ignore changes to some fields by resetting the field values.
689+
//
690+
// For instance, spec resource strategies should reset the status, and status subresource
691+
// strategies should reset the spec.
692+
//
693+
// Strategies that reset fields must report to the field manager which fields are
694+
// reset by implementing either the ResetFieldsStrategy or the ResetFieldsFilterStrategy
695+
// interface.
696+
//
697+
// For subresources that provide write access to only specific nested fields
698+
// fieldpath.NewPatternFilter can help create a filter to reset all other fields.
699+
var resetFieldsFilter map[fieldpath.APIVersion]fieldpath.Filter
700+
resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy)
701+
if isResetFieldsStrategy {
702+
resetFieldsFilter = fieldpath.NewExcludeFilterSetMap(resetFieldsStrategy.GetResetFields())
703+
}
704+
if resetFieldsStrategy, isResetFieldsFilterStrategy := storage.(rest.ResetFieldsFilterStrategy); isResetFieldsFilterStrategy {
705+
if isResetFieldsStrategy {
706+
return nil, nil, fmt.Errorf("may not implement both ResetFieldsStrategy and ResetFieldsFilterStrategy")
707+
}
708+
resetFieldsFilter = resetFieldsStrategy.GetResetFieldsFilter()
691709
}
692710

693711
reqScope.FieldManager, err = managedfields.NewDefaultFieldManager(
@@ -698,7 +716,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
698716
fqKindToRegister,
699717
reqScope.HubGroupVersion,
700718
subresource,
701-
resetFields,
719+
resetFieldsFilter,
702720
)
703721
if err != nil {
704722
return nil, nil, fmt.Errorf("failed to create field manager: %v", err)

staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ import (
2222
"net/http"
2323
"net/url"
2424

25+
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
26+
2527
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
2628
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2729
"k8s.io/apimachinery/pkg/runtime"
2830
"k8s.io/apimachinery/pkg/runtime/schema"
2931
"k8s.io/apimachinery/pkg/watch"
30-
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
3132
)
3233

3334
//TODO:
@@ -387,6 +388,12 @@ type ResetFieldsStrategy interface {
387388
GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set
388389
}
389390

391+
// ResetFieldsFilterStrategy is an optional interface that a storage object can
392+
// implement if it wishes to provide a fields filter reset by its strategies.
393+
type ResetFieldsFilterStrategy interface {
394+
GetResetFieldsFilter() map[fieldpath.APIVersion]fieldpath.Filter
395+
}
396+
390397
// CreateUpdateResetFieldsStrategy is a union of RESTCreateUpdateStrategy
391398
// and ResetFieldsStrategy.
392399
type CreateUpdateResetFieldsStrategy interface {

0 commit comments

Comments
 (0)