Skip to content

Commit 1183561

Browse files
committed
[KEP-4817] Add limits on conditions and IPs + fix documentation
Signed-off-by: Lionel Jouin <[email protected]>
1 parent c1dd8c6 commit 1183561

File tree

5 files changed

+92
-16
lines changed

5 files changed

+92
-16
lines changed

pkg/apis/resource/types.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -1020,12 +1020,17 @@ type AllocatedDeviceStatus struct {
10201020
// If the device has been configured according to the class and claim
10211021
// config references, the `Ready` condition should be True.
10221022
//
1023+
// Must not contain more than 8 entries.
1024+
//
10231025
// +optional
1024-
// +listType=atomic
1026+
// +listType=map
1027+
// +listMapKey=type
10251028
Conditions []metav1.Condition
10261029

10271030
// Data contains arbitrary driver-specific data.
10281031
//
1032+
// The length of the raw data must be smaller or equal to 10 Ki.
1033+
//
10291034
// +optional
10301035
Data runtime.RawExtension
10311036

@@ -1041,7 +1046,9 @@ type AllocatedDeviceStatus struct {
10411046
type NetworkDeviceData struct {
10421047
// InterfaceName specifies the name of the network interface associated with
10431048
// the allocated device. This might be the name of a physical or virtual
1044-
// network interface.
1049+
// network interface being configured in the pod.
1050+
//
1051+
// Must not be longer than 256 characters.
10451052
//
10461053
// +optional
10471054
InterfaceName string
@@ -1052,12 +1059,16 @@ type NetworkDeviceData struct {
10521059
// associated subnet mask.
10531060
// e.g.: "192.0.2.5/24" for IPv4 and "2001:db8::5/64" for IPv6.
10541061
//
1062+
// Must not contain more than 16 entries.
1063+
//
10551064
// +optional
10561065
// +listType=atomic
10571066
IPs []string
10581067

10591068
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
10601069
//
1070+
// Must not be longer than 128 characters.
1071+
//
10611072
// +optional
10621073
HardwareAddress string
10631074
}

pkg/apis/resource/validation/validation.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,9 @@ func validateDeviceStatus(device resource.AllocatedDeviceStatus, fldPath *field.
748748
if !allocatedDevices.Has(deviceID) {
749749
allErrs = append(allErrs, field.Invalid(fldPath, deviceID, "must be an allocated device in the claim"))
750750
}
751+
if len(device.Conditions) > maxConditions {
752+
allErrs = append(allErrs, field.TooMany(fldPath.Child("conditions"), len(device.Conditions), maxConditions))
753+
}
751754
allErrs = append(allErrs, metav1validation.ValidateConditions(device.Conditions, fldPath.Child("conditions"))...)
752755
if len(device.Data.Raw) > 0 { // Data is an optional field.
753756
allErrs = append(allErrs, validateRawExtension(device.Data, fldPath.Child("data"), false)...)
@@ -778,6 +781,8 @@ func validateRawExtension(rawExtension runtime.RawExtension, fldPath *field.Path
778781
return allErrs
779782
}
780783

784+
const maxConditions int = 8
785+
const maxIPs int = 16
781786
const interfaceNameMaxLength int = 256
782787
const hardwareAddressMaxLength int = 128
783788

@@ -795,7 +800,7 @@ func validateNetworkDeviceData(networkDeviceData *resource.NetworkDeviceData, fl
795800
allErrs = append(allErrs, field.TooLong(fldPath.Child("hardwareAddress"), "" /* unused */, hardwareAddressMaxLength))
796801
}
797802

798-
allErrs = append(allErrs, validateSet(networkDeviceData.IPs, -1,
803+
allErrs = append(allErrs, validateSet(networkDeviceData.IPs, maxIPs,
799804
func(address string, fldPath *field.Path) field.ErrorList {
800805
return validation.IsValidCIDR(fldPath, address)
801806
},

pkg/apis/resource/validation/validation_resourceclaim_test.go

+55-9
Original file line numberDiff line numberDiff line change
@@ -994,13 +994,14 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
994994
Pool: goodName,
995995
Device: goodName,
996996
Conditions: []metav1.Condition{
997-
{
998-
Type: "test",
999-
Status: metav1.ConditionTrue,
1000-
Reason: "test_reason",
1001-
LastTransitionTime: metav1.Now(),
1002-
ObservedGeneration: 0,
1003-
},
997+
{Type: "test-0", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
998+
{Type: "test-1", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
999+
{Type: "test-2", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1000+
{Type: "test-3", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1001+
{Type: "test-4", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1002+
{Type: "test-5", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1003+
{Type: "test-6", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1004+
{Type: "test-7", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
10041005
},
10051006
Data: runtime.RawExtension{
10061007
Raw: []byte(`{"kind": "foo", "apiVersion": "dra.example.com/v1"}`),
@@ -1013,6 +1014,8 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
10131014
"2001:db8::/64",
10141015
"10.9.8.1/24",
10151016
"2001:db8::1/64",
1017+
"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",
1018+
"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",
10161019
},
10171020
},
10181021
},
@@ -1096,9 +1099,11 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
10961099
},
10971100
deviceStatusFeatureGate: true,
10981101
},
1099-
"invalid-data-device-status-too-long": {
1102+
"invalid-data-device-status-limits": {
11001103
wantFailures: field.ErrorList{
1104+
field.TooMany(field.NewPath("status", "devices").Index(0).Child("conditions"), maxConditions+1, maxConditions),
11011105
field.TooLong(field.NewPath("status", "devices").Index(0).Child("data"), "" /* unused */, resource.OpaqueParametersMaxLength),
1106+
field.TooMany(field.NewPath("status", "devices").Index(0).Child("networkData", "ips"), maxIPs+1, maxIPs),
11021107
},
11031108
oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(),
11041109
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
@@ -1108,6 +1113,23 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
11081113
Pool: goodName,
11091114
Device: goodName,
11101115
Data: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)},
1116+
Conditions: []metav1.Condition{
1117+
{Type: "test-0", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1118+
{Type: "test-1", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1119+
{Type: "test-2", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1120+
{Type: "test-3", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1121+
{Type: "test-4", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1122+
{Type: "test-5", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1123+
{Type: "test-6", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1124+
{Type: "test-7", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1125+
{Type: "test-8", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1126+
},
1127+
NetworkData: &resource.NetworkDeviceData{
1128+
IPs: []string{
1129+
"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",
1130+
"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",
1131+
},
1132+
},
11111133
},
11121134
}
11131135
return claim
@@ -1206,9 +1228,11 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
12061228
},
12071229
deviceStatusFeatureGate: false,
12081230
},
1209-
"invalid-data-device-status-too-long-feature-gate": {
1231+
"invalid-data-device-status-limits-feature-gate": {
12101232
wantFailures: field.ErrorList{
1233+
field.TooMany(field.NewPath("status", "devices").Index(0).Child("conditions"), maxConditions+1, maxConditions),
12111234
field.TooLong(field.NewPath("status", "devices").Index(0).Child("data"), "" /* unused */, resource.OpaqueParametersMaxLength),
1235+
field.TooMany(field.NewPath("status", "devices").Index(0).Child("networkData", "ips"), maxIPs+1, maxIPs),
12121236
},
12131237
oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(),
12141238
update: func(claim *resource.ResourceClaim) *resource.ResourceClaim {
@@ -1218,6 +1242,23 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
12181242
Pool: goodName,
12191243
Device: goodName,
12201244
Data: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)},
1245+
Conditions: []metav1.Condition{
1246+
{Type: "test-0", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1247+
{Type: "test-1", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1248+
{Type: "test-2", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1249+
{Type: "test-3", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1250+
{Type: "test-4", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1251+
{Type: "test-5", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1252+
{Type: "test-6", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1253+
{Type: "test-7", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1254+
{Type: "test-8", Status: metav1.ConditionTrue, Reason: "test_reason", LastTransitionTime: metav1.Now(), ObservedGeneration: 0},
1255+
},
1256+
NetworkData: &resource.NetworkDeviceData{
1257+
IPs: []string{
1258+
"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",
1259+
"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",
1260+
},
1261+
},
12211262
},
12221263
}
12231264
return claim
@@ -1250,6 +1291,11 @@ func TestValidateClaimStatusUpdate(t *testing.T) {
12501291

12511292
scenario.oldClaim.ResourceVersion = "1"
12521293
errs := ValidateResourceClaimStatusUpdate(scenario.update(scenario.oldClaim.DeepCopy()), scenario.oldClaim)
1294+
1295+
if name == "invalid-data-device-status-limits-feature-gate" {
1296+
fmt.Println(errs)
1297+
fmt.Println(scenario.wantFailures)
1298+
}
12531299
assertFailures(t, scenario.wantFailures, errs)
12541300
})
12551301
}

staging/src/k8s.io/api/resource/v1alpha3/types.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -1032,11 +1032,14 @@ type AllocatedDeviceStatus struct {
10321032
// config references, the `Ready` condition should be True.
10331033
//
10341034
// +optional
1035-
// +listType=atomic
1035+
// +listType=map
1036+
// +listMapKey=type
10361037
Conditions []metav1.Condition `json:"conditions" protobuf:"bytes,4,opt,name=conditions"`
10371038

10381039
// Data contains arbitrary driver-specific data.
10391040
//
1041+
// The length of the raw data must be smaller or equal to 10 Ki.
1042+
//
10401043
// +optional
10411044
Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"`
10421045

@@ -1052,7 +1055,9 @@ type AllocatedDeviceStatus struct {
10521055
type NetworkDeviceData struct {
10531056
// InterfaceName specifies the name of the network interface associated with
10541057
// the allocated device. This might be the name of a physical or virtual
1055-
// network interface.
1058+
// network interface being configured in the pod.
1059+
//
1060+
// Must not be longer than 256 characters.
10561061
//
10571062
// +optional
10581063
InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
@@ -1069,6 +1074,8 @@ type NetworkDeviceData struct {
10691074

10701075
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
10711076
//
1077+
// Must not be longer than 128 characters.
1078+
//
10721079
// +optional
10731080
HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"`
10741081
}

staging/src/k8s.io/api/resource/v1beta1/types.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -1035,11 +1035,14 @@ type AllocatedDeviceStatus struct {
10351035
// config references, the `Ready` condition should be True.
10361036
//
10371037
// +optional
1038-
// +listType=atomic
1038+
// +listType=map
1039+
// +listMapKey=type
10391040
Conditions []metav1.Condition `json:"conditions" protobuf:"bytes,4,opt,name=conditions"`
10401041

10411042
// Data contains arbitrary driver-specific data.
10421043
//
1044+
// The length of the raw data must be smaller or equal to 10 Ki.
1045+
//
10431046
// +optional
10441047
Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"`
10451048

@@ -1055,7 +1058,9 @@ type AllocatedDeviceStatus struct {
10551058
type NetworkDeviceData struct {
10561059
// InterfaceName specifies the name of the network interface associated with
10571060
// the allocated device. This might be the name of a physical or virtual
1058-
// network interface.
1061+
// network interface being configured in the pod.
1062+
//
1063+
// Must not be longer than 256 characters.
10591064
//
10601065
// +optional
10611066
InterfaceName string `json:"interfaceName,omitempty" protobuf:"bytes,1,opt,name=interfaceName"`
@@ -1072,6 +1077,8 @@ type NetworkDeviceData struct {
10721077

10731078
// HardwareAddress represents the hardware address (e.g. MAC Address) of the device's network interface.
10741079
//
1080+
// Must not be longer than 128 characters.
1081+
//
10751082
// +optional
10761083
HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"`
10771084
}

0 commit comments

Comments
 (0)