mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 09:22:44 +00:00
[KEP-4817] Add limits on conditions and IPs + fix documentation
Signed-off-by: Lionel Jouin <lionel.jouin@est.tech>
This commit is contained in:
parent
c1dd8c6d04
commit
118356175d
@ -1020,12 +1020,17 @@ type AllocatedDeviceStatus struct {
|
|||||||
// If the device has been configured according to the class and claim
|
// If the device has been configured according to the class and claim
|
||||||
// config references, the `Ready` condition should be True.
|
// config references, the `Ready` condition should be True.
|
||||||
//
|
//
|
||||||
|
// Must not contain more than 8 entries.
|
||||||
|
//
|
||||||
// +optional
|
// +optional
|
||||||
// +listType=atomic
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
Conditions []metav1.Condition
|
Conditions []metav1.Condition
|
||||||
|
|
||||||
// Data contains arbitrary driver-specific data.
|
// Data contains arbitrary driver-specific data.
|
||||||
//
|
//
|
||||||
|
// The length of the raw data must be smaller or equal to 10 Ki.
|
||||||
|
//
|
||||||
// +optional
|
// +optional
|
||||||
Data runtime.RawExtension
|
Data runtime.RawExtension
|
||||||
|
|
||||||
@ -1041,7 +1046,9 @@ type AllocatedDeviceStatus struct {
|
|||||||
type NetworkDeviceData struct {
|
type NetworkDeviceData struct {
|
||||||
// InterfaceName specifies the name of the network interface associated with
|
// InterfaceName specifies the name of the network interface associated with
|
||||||
// the allocated device. This might be the name of a physical or virtual
|
// the allocated device. This might be the name of a physical or virtual
|
||||||
// network interface.
|
// network interface being configured in the pod.
|
||||||
|
//
|
||||||
|
// Must not be longer than 256 characters.
|
||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
InterfaceName string
|
InterfaceName string
|
||||||
@ -1052,12 +1059,16 @@ type NetworkDeviceData struct {
|
|||||||
// associated subnet mask.
|
// associated subnet mask.
|
||||||
// e.g.: "192.0.2.5/24" for IPv4 and "2001:db8::5/64" for IPv6.
|
// e.g.: "192.0.2.5/24" for IPv4 and "2001:db8::5/64" for IPv6.
|
||||||
//
|
//
|
||||||
|
// Must not contain more than 16 entries.
|
||||||
|
//
|
||||||
// +optional
|
// +optional
|
||||||
// +listType=atomic
|
// +listType=atomic
|
||||||
IPs []string
|
IPs []string
|
||||||
|
|
||||||
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
|
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
|
||||||
//
|
//
|
||||||
|
// Must not be longer than 128 characters.
|
||||||
|
//
|
||||||
// +optional
|
// +optional
|
||||||
HardwareAddress string
|
HardwareAddress string
|
||||||
}
|
}
|
||||||
|
@ -748,6 +748,9 @@ func validateDeviceStatus(device resource.AllocatedDeviceStatus, fldPath *field.
|
|||||||
if !allocatedDevices.Has(deviceID) {
|
if !allocatedDevices.Has(deviceID) {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, deviceID, "must be an allocated device in the claim"))
|
allErrs = append(allErrs, field.Invalid(fldPath, deviceID, "must be an allocated device in the claim"))
|
||||||
}
|
}
|
||||||
|
if len(device.Conditions) > maxConditions {
|
||||||
|
allErrs = append(allErrs, field.TooMany(fldPath.Child("conditions"), len(device.Conditions), maxConditions))
|
||||||
|
}
|
||||||
allErrs = append(allErrs, metav1validation.ValidateConditions(device.Conditions, fldPath.Child("conditions"))...)
|
allErrs = append(allErrs, metav1validation.ValidateConditions(device.Conditions, fldPath.Child("conditions"))...)
|
||||||
if len(device.Data.Raw) > 0 { // Data is an optional field.
|
if len(device.Data.Raw) > 0 { // Data is an optional field.
|
||||||
allErrs = append(allErrs, validateRawExtension(device.Data, fldPath.Child("data"), false)...)
|
allErrs = append(allErrs, validateRawExtension(device.Data, fldPath.Child("data"), false)...)
|
||||||
@ -778,6 +781,8 @@ func validateRawExtension(rawExtension runtime.RawExtension, fldPath *field.Path
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const maxConditions int = 8
|
||||||
|
const maxIPs int = 16
|
||||||
const interfaceNameMaxLength int = 256
|
const interfaceNameMaxLength int = 256
|
||||||
const hardwareAddressMaxLength int = 128
|
const hardwareAddressMaxLength int = 128
|
||||||
|
|
||||||
@ -795,7 +800,7 @@ func validateNetworkDeviceData(networkDeviceData *resource.NetworkDeviceData, fl
|
|||||||
allErrs = append(allErrs, field.TooLong(fldPath.Child("hardwareAddress"), "" /* unused */, hardwareAddressMaxLength))
|
allErrs = append(allErrs, field.TooLong(fldPath.Child("hardwareAddress"), "" /* unused */, hardwareAddressMaxLength))
|
||||||
}
|
}
|
||||||
|
|
||||||
allErrs = append(allErrs, validateSet(networkDeviceData.IPs, -1,
|
allErrs = append(allErrs, validateSet(networkDeviceData.IPs, maxIPs,
|
||||||
func(address string, fldPath *field.Path) field.ErrorList {
|
func(address string, fldPath *field.Path) field.ErrorList {
|
||||||
return validation.IsValidCIDR(fldPath, address)
|
return validation.IsValidCIDR(fldPath, address)
|
||||||
},
|
},
|
||||||
|
@ -994,13 +994,14 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
Pool: goodName,
|
Pool: goodName,
|
||||||
Device: goodName,
|
Device: goodName,
|
||||||
Conditions: []metav1.Condition{
|
Conditions: []metav1.Condition{
|
||||||
{
|
{Type: "test-0", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
Type: "test",
|
{Type: "test-1", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
Status: metav1.ConditionTrue,
|
{Type: "test-2", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
Reason: "test_reason",
|
{Type: "test-3", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
LastTransitionTime: metav1.Now(),
|
{Type: "test-4", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
ObservedGeneration: 0,
|
{Type: "test-5", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
},
|
{Type: "test-6", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-7", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
},
|
},
|
||||||
Data: runtime.RawExtension{
|
Data: runtime.RawExtension{
|
||||||
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
|
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
|
||||||
@ -1013,6 +1014,8 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
"2001:db8::/64",
|
"2001:db8::/64",
|
||||||
"10.9.8.1/24",
|
"10.9.8.1/24",
|
||||||
"2001:db8::1/64",
|
"2001:db8::1/64",
|
||||||
|
"10.9.8.2/24", "10.9.8.3/24", "10.9.8.4/24", "10.9.8.5/24", "10.9.8.6/24", "10.9.8.7/24",
|
||||||
|
"10.9.8.8/24", "10.9.8.9/24", "10.9.8.10/24", "10.9.8.11/24", "10.9.8.12/24", "10.9.8.13/24",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1096,9 +1099,11 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
deviceStatusFeatureGate: true,
|
deviceStatusFeatureGate: true,
|
||||||
},
|
},
|
||||||
"invalid-data-device-status-too-long": {
|
"invalid-data-device-status-limits": {
|
||||||
wantFailures: field.ErrorList{
|
wantFailures: field.ErrorList{
|
||||||
|
field.TooMany(field.NewPath("status", "devices").Index(0).Child("conditions"), maxConditions+1, maxConditions),
|
||||||
field.TooLong(field.NewPath("status", "devices").Index(0).Child("data"), "" /* unused */, resource.OpaqueParametersMaxLength),
|
field.TooLong(field.NewPath("status", "devices").Index(0).Child("data"), "" /* unused */, resource.OpaqueParametersMaxLength),
|
||||||
|
field.TooMany(field.NewPath("status", "devices").Index(0).Child("networkData", "ips"), maxIPs+1, maxIPs),
|
||||||
},
|
},
|
||||||
oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(),
|
oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(),
|
||||||
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
|
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
|
||||||
@ -1108,6 +1113,23 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
Pool: goodName,
|
Pool: goodName,
|
||||||
Device: goodName,
|
Device: goodName,
|
||||||
Data: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)},
|
Data: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)},
|
||||||
|
Conditions: []metav1.Condition{
|
||||||
|
{Type: "test-0", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-1", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-2", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-3", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-4", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-5", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-6", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-7", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-8", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
},
|
||||||
|
NetworkData: &resource.NetworkDeviceData{
|
||||||
|
IPs: []string{
|
||||||
|
"10.9.8.0/24", "10.9.8.1/24", "10.9.8.2/24", "10.9.8.3/24", "10.9.8.4/24", "10.9.8.5/24", "10.9.8.6/24", "10.9.8.7/24", "10.9.8.8/24",
|
||||||
|
"10.9.8.9/24", "10.9.8.10/24", "10.9.8.11/24", "10.9.8.12/24", "10.9.8.13/24", "10.9.8.14/24", "10.9.8.15/24", "10.9.8.16/24",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return claim
|
return claim
|
||||||
@ -1206,9 +1228,11 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
deviceStatusFeatureGate: false,
|
deviceStatusFeatureGate: false,
|
||||||
},
|
},
|
||||||
"invalid-data-device-status-too-long-feature-gate": {
|
"invalid-data-device-status-limits-feature-gate": {
|
||||||
wantFailures: field.ErrorList{
|
wantFailures: field.ErrorList{
|
||||||
|
field.TooMany(field.NewPath("status", "devices").Index(0).Child("conditions"), maxConditions+1, maxConditions),
|
||||||
field.TooLong(field.NewPath("status", "devices").Index(0).Child("data"), "" /* unused */, resource.OpaqueParametersMaxLength),
|
field.TooLong(field.NewPath("status", "devices").Index(0).Child("data"), "" /* unused */, resource.OpaqueParametersMaxLength),
|
||||||
|
field.TooMany(field.NewPath("status", "devices").Index(0).Child("networkData", "ips"), maxIPs+1, maxIPs),
|
||||||
},
|
},
|
||||||
oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(),
|
oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(),
|
||||||
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
|
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
|
||||||
@ -1218,6 +1242,23 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
Pool: goodName,
|
Pool: goodName,
|
||||||
Device: goodName,
|
Device: goodName,
|
||||||
Data: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)},
|
Data: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)},
|
||||||
|
Conditions: []metav1.Condition{
|
||||||
|
{Type: "test-0", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-1", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-2", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-3", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-4", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-5", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-6", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-7", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
{Type: "test-8", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
|
||||||
|
},
|
||||||
|
NetworkData: &resource.NetworkDeviceData{
|
||||||
|
IPs: []string{
|
||||||
|
"10.9.8.0/24", "10.9.8.1/24", "10.9.8.2/24", "10.9.8.3/24", "10.9.8.4/24", "10.9.8.5/24", "10.9.8.6/24", "10.9.8.7/24", "10.9.8.8/24",
|
||||||
|
"10.9.8.9/24", "10.9.8.10/24", "10.9.8.11/24", "10.9.8.12/24", "10.9.8.13/24", "10.9.8.14/24", "10.9.8.15/24", "10.9.8.16/24",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return claim
|
return claim
|
||||||
@ -1250,6 +1291,11 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
|
|||||||
|
|
||||||
scenario.oldClaim.ResourceVersion = "1"
|
scenario.oldClaim.ResourceVersion = "1"
|
||||||
errs := ValidateResourceClaimStatusUpdate(scenario.update(scenario.oldClaim.DeepCopy()), scenario.oldClaim)
|
errs := ValidateResourceClaimStatusUpdate(scenario.update(scenario.oldClaim.DeepCopy()), scenario.oldClaim)
|
||||||
|
|
||||||
|
if name == "invalid-data-device-status-limits-feature-gate" {
|
||||||
|
fmt.Println(errs)
|
||||||
|
fmt.Println(scenario.wantFailures)
|
||||||
|
}
|
||||||
assertFailures(t, scenario.wantFailures, errs)
|
assertFailures(t, scenario.wantFailures, errs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1032,11 +1032,14 @@ type AllocatedDeviceStatus struct {
|
|||||||
// config references, the `Ready` condition should be True.
|
// config references, the `Ready` condition should be True.
|
||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
// +listType=atomic
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
Conditions []metav1.Condition `json:"conditions" protobuf:"bytes,4,opt,name=conditions"`
|
Conditions []metav1.Condition `json:"conditions" protobuf:"bytes,4,opt,name=conditions"`
|
||||||
|
|
||||||
// Data contains arbitrary driver-specific data.
|
// Data contains arbitrary driver-specific data.
|
||||||
//
|
//
|
||||||
|
// The length of the raw data must be smaller or equal to 10 Ki.
|
||||||
|
//
|
||||||
// +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"`
|
||||||
|
|
||||||
@ -1052,7 +1055,9 @@ type AllocatedDeviceStatus struct {
|
|||||||
type NetworkDeviceData struct {
|
type NetworkDeviceData struct {
|
||||||
// InterfaceName specifies the name of the network interface associated with
|
// InterfaceName specifies the name of the network interface associated with
|
||||||
// the allocated device. This might be the name of a physical or virtual
|
// the allocated device. This might be the name of a physical or virtual
|
||||||
// network interface.
|
// network interface being configured in the pod.
|
||||||
|
//
|
||||||
|
// Must not be longer than 256 characters.
|
||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
|
InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
|
||||||
@ -1069,6 +1074,8 @@ type NetworkDeviceData struct {
|
|||||||
|
|
||||||
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
|
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
|
||||||
//
|
//
|
||||||
|
// Must not be longer than 128 characters.
|
||||||
|
//
|
||||||
// +optional
|
// +optional
|
||||||
HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"`
|
HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"`
|
||||||
}
|
}
|
||||||
|
@ -1035,11 +1035,14 @@ type AllocatedDeviceStatus struct {
|
|||||||
// config references, the `Ready` condition should be True.
|
// config references, the `Ready` condition should be True.
|
||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
// +listType=atomic
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
Conditions []metav1.Condition `json:"conditions" protobuf:"bytes,4,opt,name=conditions"`
|
Conditions []metav1.Condition `json:"conditions" protobuf:"bytes,4,opt,name=conditions"`
|
||||||
|
|
||||||
// Data contains arbitrary driver-specific data.
|
// Data contains arbitrary driver-specific data.
|
||||||
//
|
//
|
||||||
|
// The length of the raw data must be smaller or equal to 10 Ki.
|
||||||
|
//
|
||||||
// +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"`
|
||||||
|
|
||||||
@ -1055,7 +1058,9 @@ type AllocatedDeviceStatus struct {
|
|||||||
type NetworkDeviceData struct {
|
type NetworkDeviceData struct {
|
||||||
// InterfaceName specifies the name of the network interface associated with
|
// InterfaceName specifies the name of the network interface associated with
|
||||||
// the allocated device. This might be the name of a physical or virtual
|
// the allocated device. This might be the name of a physical or virtual
|
||||||
// network interface.
|
// network interface being configured in the pod.
|
||||||
|
//
|
||||||
|
// Must not be longer than 256 characters.
|
||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
|
InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
|
||||||
@ -1072,6 +1077,8 @@ type NetworkDeviceData struct {
|
|||||||
|
|
||||||
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
|
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
|
||||||
//
|
//
|
||||||
|
// Must not be longer than 128 characters.
|
||||||
|
//
|
||||||
// +optional
|
// +optional
|
||||||
HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"`
|
HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user