[KEP-4817] Remove pointer on Data, InterfaceName and HWAddress fields

Adapat validation and tests based on these API changes

Signed-off-by: Lionel Jouin <lionel.jouin@est.tech>
This commit is contained in:
Lionel Jouin 2024-10-28 14:41:18 +01:00
parent 8be335a755
commit cb9ee1d4fe
7 changed files with 37 additions and 52 deletions

View File

@ -62,7 +62,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
// //
// This is necessary because randomly generated content // This is necessary because randomly generated content
// might be valid JSON which changes during re-encoding. // might be valid JSON which changes during re-encoding.
r.Data = &runtime.RawExtension{Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`)} r.Data = runtime.RawExtension{Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`)}
}, },
} }
} }

View File

@ -1027,7 +1027,7 @@ type AllocatedDeviceStatus struct {
// Data contains arbitrary driver-specific data. // Data contains arbitrary driver-specific data.
// //
// +optional // +optional
Data *runtime.RawExtension Data runtime.RawExtension
// NetworkData contains network-related information specific to the device. // NetworkData contains network-related information specific to the device.
// //
@ -1044,7 +1044,7 @@ type NetworkDeviceData struct {
// network interface. // network interface.
// //
// +optional // +optional
InterfaceName *string InterfaceName string
// Addresses lists the network addresses assigned to the device's network interface. // Addresses lists the network addresses assigned to the device's network interface.
// This can include both IPv4 and IPv6 addresses. // This can include both IPv4 and IPv6 addresses.
@ -1059,5 +1059,5 @@ type NetworkDeviceData struct {
// HWAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // HWAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
// //
// +optional // +optional
HWAddress *string HWAddress string
} }

View File

@ -257,24 +257,7 @@ func validateDeviceConfiguration(config resource.DeviceConfiguration, fldPath *f
func validateOpaqueConfiguration(config resource.OpaqueDeviceConfiguration, fldPath *field.Path, stored bool) field.ErrorList { func validateOpaqueConfiguration(config resource.OpaqueDeviceConfiguration, fldPath *field.Path, stored bool) field.ErrorList {
var allErrs field.ErrorList var allErrs field.ErrorList
allErrs = append(allErrs, validateDriverName(config.Driver, fldPath.Child("driver"))...) allErrs = append(allErrs, validateDriverName(config.Driver, fldPath.Child("driver"))...)
// Validation of RawExtension as in https://github.com/kubernetes/kubernetes/pull/125549/ allErrs = append(allErrs, validateRawExtension(config.Parameters, fldPath.Child("parameters"))...)
var v any
if len(config.Parameters.Raw) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("parameters"), ""))
} else if !stored && len(config.Parameters.Raw) > resource.OpaqueParametersMaxLength {
// Don't even bother with parsing when too large.
// Only applies on create. Existing parameters are grand-fathered in
// because the limit was introduced in 1.32. This also means that it
// can be changed in the future.
allErrs = append(allErrs, field.TooLong(fldPath.Child("parameters"), "" /* unused */, resource.OpaqueParametersMaxLength))
} else if err := json.Unmarshal(config.Parameters.Raw, &v); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("parameters"), "<value omitted>", fmt.Sprintf("error parsing data as JSON: %v", err.Error())))
} else if v == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("parameters"), ""))
} else if _, isObject := v.(map[string]any); !isObject {
allErrs = append(allErrs, field.Invalid(fldPath.Child("parameters"), "<value omitted>", "parameters must be a valid JSON object"))
}
return allErrs return allErrs
} }
@ -770,20 +753,23 @@ func validateDeviceStatus(device resource.AllocatedDeviceStatus, fldPath *field.
var allErrs field.ErrorList var allErrs field.ErrorList
return allErrs return allErrs
}, fldPath.Child("conditions"))...) }, fldPath.Child("conditions"))...)
allErrs = append(allErrs, validateRawExtension(device.Data, fldPath.Child("data"))...) if len(device.Data.Raw) > 0 { // Data is an optional field.
allErrs = append(allErrs, validateRawExtension(device.Data, fldPath.Child("data"))...)
}
allErrs = append(allErrs, validateNetworkDeviceData(device.NetworkData, fldPath.Child("networkData"))...) allErrs = append(allErrs, validateNetworkDeviceData(device.NetworkData, fldPath.Child("networkData"))...)
return allErrs return allErrs
} }
func validateRawExtension(rawExtension *runtime.RawExtension, fldPath *field.Path) field.ErrorList { func validateRawExtension(rawExtension runtime.RawExtension, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList var allErrs field.ErrorList
if rawExtension == nil {
return allErrs
}
// Validation of RawExtension as in https://github.com/kubernetes/kubernetes/pull/125549/ // Validation of RawExtension as in https://github.com/kubernetes/kubernetes/pull/125549/
var v any var v any
if err := json.Unmarshal(rawExtension.Raw, &v); err != nil { if len(rawExtension.Raw) == 0 {
allErrs = append(allErrs, field.Required(fldPath, ""))
} else if err := json.Unmarshal(rawExtension.Raw, &v); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, "<value omitted>", fmt.Sprintf("error parsing data: %v", err.Error()))) allErrs = append(allErrs, field.Invalid(fldPath, "<value omitted>", fmt.Sprintf("error parsing data: %v", err.Error())))
} else if v == nil {
allErrs = append(allErrs, field.Required(fldPath, ""))
} else if _, isObject := v.(map[string]any); !isObject { } else if _, isObject := v.(map[string]any); !isObject {
allErrs = append(allErrs, field.Invalid(fldPath, "<value omitted>", "parameters must be a valid JSON object")) allErrs = append(allErrs, field.Invalid(fldPath, "<value omitted>", "parameters must be a valid JSON object"))
} }

View File

@ -1000,16 +1000,16 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
Status: metav1.ConditionTrue, Status: metav1.ConditionTrue,
}, },
}, },
Data: &runtime.RawExtension{ Data: runtime.RawExtension{
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`), Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
}, },
NetworkData: &resource.NetworkDeviceData{ NetworkData: &resource.NetworkDeviceData{
InterfaceName: ptr.To("net-1"), InterfaceName: "net-1",
Addresses: []string{ Addresses: []string{
"10.9.8.0/24", "10.9.8.0/24",
"2001:db8::/64", "2001:db8::/64",
}, },
HWAddress: ptr.To("ea:9f:cb:40:b1:7b"), HWAddress: "ea:9f:cb:40:b1:7b",
}, },
}, },
} }
@ -1075,7 +1075,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
Driver: goodName, Driver: goodName,
Pool: goodName, Pool: goodName,
Device: goodName, Device: goodName,
Data: &runtime.RawExtension{ Data: runtime.RawExtension{
Raw: []byte(`foo`), Raw: []byte(`foo`),
}, },
}, },
@ -1154,7 +1154,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
Driver: goodName, Driver: goodName,
Pool: goodName, Pool: goodName,
Device: goodName, Device: goodName,
Data: &runtime.RawExtension{ Data: runtime.RawExtension{
Raw: []byte(`foo`), Raw: []byte(`foo`),
}, },
}, },

View File

@ -1038,7 +1038,7 @@ type AllocatedDeviceStatus struct {
// Data contains arbitrary driver-specific data. // Data contains arbitrary driver-specific data.
// //
// +optional // +optional
Data *runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"` Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"`
// NetworkData contains network-related information specific to the device. // NetworkData contains network-related information specific to the device.
// //
@ -1055,7 +1055,7 @@ type NetworkDeviceData struct {
// network interface. // network interface.
// //
// +optional // +optional
InterfaceName *string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"` InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
// Addresses lists the network addresses assigned to the device's network interface. // Addresses lists the network addresses assigned to the device's network interface.
// This can include both IPv4 and IPv6 addresses. // This can include both IPv4 and IPv6 addresses.
@ -1070,5 +1070,5 @@ type NetworkDeviceData struct {
// HWAddress represents the hardware address (e.g. MAC Address) of the device's network interface. // HWAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
// //
// +optional // +optional
HWAddress *string `json:"hwAddress,omitempty" protobuf:"bytes,3,opt,name=hwAddress"` HWAddress string `json:"hwAddress,omitempty" protobuf:"bytes,3,opt,name=hwAddress"`
} }

View File

@ -438,11 +438,11 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation,
Pool: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Pool, Pool: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Pool,
Device: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Device, Device: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Device,
Conditions: []metav1.Condition{{Type: "a", Status: "b", Message: "c", Reason: "d"}}, Conditions: []metav1.Condition{{Type: "a", Status: "b", Message: "c", Reason: "d"}},
Data: &runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}, Data: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)},
NetworkData: &resourceapi.NetworkDeviceData{ NetworkData: &resourceapi.NetworkDeviceData{
InterfaceName: ptr.To("inf1"), InterfaceName: "inf1",
Addresses: []string{"10.9.8.0/24", "2001:db8::/64"}, Addresses: []string{"10.9.8.0/24", "2001:db8::/64"},
HWAddress: ptr.To("bc:1c:b6:3e:b8:25"), HWAddress: "bc:1c:b6:3e:b8:25",
}, },
}) })
// Updates the ResourceClaim from the driver on the same node as the pod. // Updates the ResourceClaim from the driver on the same node as the pod.
@ -457,11 +457,11 @@ var _ = framework.SIGDescribe("node")("DRA", feature.DynamicResourceAllocation,
Pool: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Pool, Pool: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Pool,
Device: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Device, Device: allocatedResourceClaim.Status.Allocation.Devices.Results[0].Device,
Conditions: []metav1.Condition{{Type: "e", Status: "f", Message: "g", Reason: "h"}}, Conditions: []metav1.Condition{{Type: "e", Status: "f", Message: "g", Reason: "h"}},
Data: &runtime.RawExtension{Raw: []byte(`{"bar":"foo"}`)}, Data: runtime.RawExtension{Raw: []byte(`{"bar":"foo"}`)},
NetworkData: &resourceapi.NetworkDeviceData{ NetworkData: &resourceapi.NetworkDeviceData{
InterfaceName: ptr.To("inf2"), InterfaceName: "inf2",
Addresses: []string{"10.9.8.1/24", "2001:db8::1/64"}, Addresses: []string{"10.9.8.1/24", "2001:db8::1/64"},
HWAddress: ptr.To("bc:1c:b6:3e:b8:26"), HWAddress: "bc:1c:b6:3e:b8:26",
}, },
} }
updatedResourceClaim2, err := driver.Nodes[scheduledPod.Spec.NodeName].ExamplePlugin.UpdateStatus(ctx, updatedResourceClaim) updatedResourceClaim2, err := driver.Nodes[scheduledPod.Spec.NodeName].ExamplePlugin.UpdateStatus(ctx, updatedResourceClaim)

View File

@ -28,7 +28,6 @@ import (
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/test/integration/framework" "k8s.io/kubernetes/test/integration/framework"
"k8s.io/utils/ptr"
) )
// TestEnableDisableDRAResourceClaimDeviceStatus first test the feature gate disabled // TestEnableDisableDRAResourceClaimDeviceStatus first test the feature gate disabled
@ -82,16 +81,16 @@ func TestEnableDisableDRAResourceClaimDeviceStatus(t *testing.T) {
Driver: "foo", Driver: "foo",
Pool: "foo", Pool: "foo",
Device: "foo", Device: "foo",
Data: &runtime.RawExtension{ Data: runtime.RawExtension{
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`), Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
}, },
NetworkData: &v1alpha3.NetworkDeviceData{ NetworkData: &v1alpha3.NetworkDeviceData{
InterfaceName: ptr.To("net-1"), InterfaceName: "net-1",
Addresses: []string{ Addresses: []string{
"10.9.8.0/24", "10.9.8.0/24",
"2001:db8::/64", "2001:db8::/64",
}, },
HWAddress: ptr.To("ea:9f:cb:40:b1:7b"), HWAddress: "ea:9f:cb:40:b1:7b",
}, },
}, },
}, },
@ -154,16 +153,16 @@ func TestEnableDisableDRAResourceClaimDeviceStatus(t *testing.T) {
Driver: "bar", Driver: "bar",
Pool: "bar", Pool: "bar",
Device: "bar", Device: "bar",
Data: &runtime.RawExtension{ Data: runtime.RawExtension{
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`), Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
}, },
NetworkData: &v1alpha3.NetworkDeviceData{ NetworkData: &v1alpha3.NetworkDeviceData{
InterfaceName: ptr.To("net-1"), InterfaceName: "net-1",
Addresses: []string{ Addresses: []string{
"10.9.8.0/24", "10.9.8.0/24",
"2001:db8::/64", "2001:db8::/64",
}, },
HWAddress: ptr.To("ea:9f:cb:40:b1:7b"), HWAddress: "ea:9f:cb:40:b1:7b",
}, },
}, },
}, },
@ -190,16 +189,16 @@ func TestEnableDisableDRAResourceClaimDeviceStatus(t *testing.T) {
Driver: "bar", Driver: "bar",
Pool: "bar", Pool: "bar",
Device: "bar", Device: "bar",
Data: &runtime.RawExtension{ Data: runtime.RawExtension{
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`), Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
}, },
NetworkData: &v1alpha3.NetworkDeviceData{ NetworkData: &v1alpha3.NetworkDeviceData{
InterfaceName: ptr.To("net-1"), InterfaceName: "net-1",
Addresses: []string{ Addresses: []string{
"10.9.8.0/24", "10.9.8.0/24",
"2001:db8::/64", "2001:db8::/64",
}, },
HWAddress: ptr.To("ea:9f:cb:40:b1:7b"), HWAddress: "ea:9f:cb:40:b1:7b",
}, },
}, },
}, },