mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-17 11:28:58 +00:00
KEP-5491: strategy(dropDisableFields) for list fields in DeviceAttribute
This commit is contained in:
@@ -197,6 +197,7 @@ func dropDisabledFields(newSlice, oldSlice *resource.ResourceSlice) {
|
||||
dropDisabledDRADeviceBindingConditionsFields(newSlice, oldSlice)
|
||||
dropDisabledDRAConsumableCapacityFields(newSlice, oldSlice)
|
||||
dropDisabledDRANodeAllocatableResourcesFields(newSlice, oldSlice)
|
||||
dropDisableDRAListTypeAttributesFields(newSlice, oldSlice)
|
||||
}
|
||||
|
||||
func dropDisabledDRADeviceTaintsFields(newSlice, oldSlice *resource.ResourceSlice) {
|
||||
@@ -348,3 +349,47 @@ func draNodeAllocatableResourcesFeatureInUse(slice *resource.ResourceSlice) bool
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func dropDisableDRAListTypeAttributesFields(newSlice, oldSlice *resource.ResourceSlice) {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.DRAListTypeAttributes) ||
|
||||
draListTypeAttributesFeatureInUse(oldSlice) {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range newSlice.Spec.Devices {
|
||||
for k, deviceAttribute := range newSlice.Spec.Devices[i].Attributes {
|
||||
if deviceAttribute.BoolValues != nil {
|
||||
deviceAttribute.BoolValues = nil
|
||||
newSlice.Spec.Devices[i].Attributes[k] = deviceAttribute
|
||||
}
|
||||
if deviceAttribute.IntValues != nil {
|
||||
deviceAttribute.IntValues = nil
|
||||
newSlice.Spec.Devices[i].Attributes[k] = deviceAttribute
|
||||
}
|
||||
if deviceAttribute.StringValues != nil {
|
||||
deviceAttribute.StringValues = nil
|
||||
newSlice.Spec.Devices[i].Attributes[k] = deviceAttribute
|
||||
}
|
||||
if deviceAttribute.VersionValues != nil {
|
||||
deviceAttribute.VersionValues = nil
|
||||
newSlice.Spec.Devices[i].Attributes[k] = deviceAttribute
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func draListTypeAttributesFeatureInUse(slice *resource.ResourceSlice) bool {
|
||||
if slice == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, device := range slice.Spec.Devices {
|
||||
for _, deviceAttribute := range device.Attributes {
|
||||
if deviceAttribute.BoolValues != nil || deviceAttribute.IntValues != nil || deviceAttribute.StringValues != nil || deviceAttribute.VersionValues != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -199,6 +199,16 @@ var sliceWithNodeAllocatableResources = func() *resource.ResourceSlice {
|
||||
return obj
|
||||
}()
|
||||
|
||||
var sliceWithListTypeAttributes = func() *resource.ResourceSlice {
|
||||
obj := slice.DeepCopy()
|
||||
obj.Spec.Devices[0].Attributes = map[resource.QualifiedName]resource.DeviceAttribute{
|
||||
resource.QualifiedName("list_attribute"): {
|
||||
StringValues: []string{"value1", "value2"},
|
||||
},
|
||||
}
|
||||
return obj
|
||||
}()
|
||||
|
||||
func TestResourceSliceStrategy(t *testing.T) {
|
||||
if Strategy.NamespaceScoped() {
|
||||
t.Errorf("ResourceSlice must not be namespace scoped")
|
||||
@@ -218,6 +228,7 @@ func TestResourceSliceStrategyCreate(t *testing.T) {
|
||||
deviceStatus bool
|
||||
consumableCapacity bool
|
||||
draNodeAllocatableResources bool
|
||||
listTypeAttributes bool
|
||||
expectedValidationError bool
|
||||
expectObj *resource.ResourceSlice
|
||||
}{
|
||||
@@ -382,6 +393,20 @@ func TestResourceSliceStrategyCreate(t *testing.T) {
|
||||
return obj
|
||||
}(),
|
||||
},
|
||||
"keep-fields-list-type-attributes": {
|
||||
obj: sliceWithListTypeAttributes,
|
||||
listTypeAttributes: true,
|
||||
expectObj: func() *resource.ResourceSlice {
|
||||
obj := sliceWithListTypeAttributes.DeepCopy()
|
||||
obj.Generation = 1
|
||||
return obj
|
||||
}(),
|
||||
},
|
||||
"drop-fields-list-type-attributes": {
|
||||
obj: sliceWithListTypeAttributes,
|
||||
listTypeAttributes: false,
|
||||
expectedValidationError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
@@ -393,6 +418,7 @@ func TestResourceSliceStrategyCreate(t *testing.T) {
|
||||
features.DRAResourceClaimDeviceStatus: tc.deviceStatus,
|
||||
features.DRAConsumableCapacity: tc.consumableCapacity,
|
||||
features.DRANodeAllocatableResources: tc.draNodeAllocatableResources,
|
||||
features.DRAListTypeAttributes: tc.listTypeAttributes,
|
||||
})
|
||||
|
||||
obj := tc.obj.DeepCopy()
|
||||
@@ -424,6 +450,7 @@ func TestResourceSliceStrategyUpdate(t *testing.T) {
|
||||
deviceStatus bool
|
||||
bindingConditions bool
|
||||
consumableCapacity bool
|
||||
listTypeAttributes bool
|
||||
expectValidationError bool
|
||||
expectObj *resource.ResourceSlice
|
||||
}{
|
||||
@@ -782,6 +809,44 @@ func TestResourceSliceStrategyUpdate(t *testing.T) {
|
||||
return obj
|
||||
}(),
|
||||
},
|
||||
"drop-list-type-attributes": {
|
||||
oldObj: slice.DeepCopy(),
|
||||
newObj: func() *resource.ResourceSlice {
|
||||
obj := sliceWithListTypeAttributes.DeepCopy()
|
||||
obj.ResourceVersion = "4"
|
||||
return obj
|
||||
}(),
|
||||
listTypeAttributes: false,
|
||||
expectValidationError: true,
|
||||
},
|
||||
"keep-list-type-attributes": {
|
||||
oldObj: sliceWithListTypeAttributes,
|
||||
newObj: func() *resource.ResourceSlice {
|
||||
obj := sliceWithListTypeAttributes.DeepCopy()
|
||||
obj.ResourceVersion = "4"
|
||||
return obj
|
||||
}(),
|
||||
listTypeAttributes: true,
|
||||
expectObj: func() *resource.ResourceSlice {
|
||||
obj := sliceWithListTypeAttributes.DeepCopy()
|
||||
obj.ResourceVersion = "4"
|
||||
return obj
|
||||
}(),
|
||||
},
|
||||
"keep-existing-list-type-attributes-without-featuregate-enabled": {
|
||||
oldObj: sliceWithListTypeAttributes,
|
||||
newObj: func() *resource.ResourceSlice {
|
||||
obj := sliceWithListTypeAttributes.DeepCopy()
|
||||
obj.ResourceVersion = "4"
|
||||
return obj
|
||||
}(),
|
||||
listTypeAttributes: false,
|
||||
expectObj: func() *resource.ResourceSlice {
|
||||
obj := sliceWithListTypeAttributes.DeepCopy()
|
||||
obj.ResourceVersion = "4"
|
||||
return obj
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testcases {
|
||||
|
||||
Reference in New Issue
Block a user