DRA: new API for 1.31
This is a complete revamp of the original API. Some of the key differences: - refocused on structured parameters and allocating devices - support for constraints across devices - support for allocating "all" or a fixed amount of similar devices in a single request - no class for ResourceClaims, instead individual device requests are associated with a mandatory DeviceClass For the sake of simplicity, optional basic types (ints, strings) where the null value is the default are represented as values in the API types. This makes Go code simpler because it doesn't have to check for nil (consumers) and values can be set directly (producers). The effect is that in protobuf, these fields always get encoded because `opt` only has an effect for pointers. The roundtrip test data for v1.29.0 and v1.30.0 changes because of the new "request" field. This is considered acceptable because the entire `claims` field in the pod spec is still alpha. The implementation is complete enough to bring up the apiserver. Adapting other components follows.
This commit is contained in:
@@ -32,10 +32,13 @@ func testResourceSlice(name, nodeName, driverName string) *resource.ResourceSlic
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
NodeName: nodeName,
|
||||
DriverName: driverName,
|
||||
ResourceModel: resource.ResourceModel{
|
||||
NamedResources: &resource.NamedResourcesResources{},
|
||||
Spec: resource.ResourceSliceSpec{
|
||||
NodeName: nodeName,
|
||||
Driver: driverName,
|
||||
Pool: resource.ResourcePool{
|
||||
Name: nodeName,
|
||||
ResourceSliceCount: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -180,22 +183,24 @@ func TestValidateResourceSlice(t *testing.T) {
|
||||
}(),
|
||||
},
|
||||
"bad-nodename": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")},
|
||||
slice: testResourceSlice(goodName, badName, driverName),
|
||||
wantFailures: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "pool", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
|
||||
field.Invalid(field.NewPath("spec", "nodeName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
|
||||
},
|
||||
slice: testResourceSlice(goodName, badName, driverName),
|
||||
},
|
||||
"bad-multi-pool-name": {
|
||||
wantFailures: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "pool", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
|
||||
field.Invalid(field.NewPath("spec", "pool", "name"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
|
||||
field.Invalid(field.NewPath("spec", "nodeName"), badName+"/"+badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
|
||||
},
|
||||
slice: testResourceSlice(goodName, badName+"/"+badName, driverName),
|
||||
},
|
||||
"bad-drivername": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")},
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec", "driver"), badName, "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')")},
|
||||
slice: testResourceSlice(goodName, goodName, badName),
|
||||
},
|
||||
|
||||
"empty-model": {
|
||||
wantFailures: field.ErrorList{field.Required(nil, "exactly one structured model field must be set")},
|
||||
slice: func() *resource.ResourceSlice {
|
||||
slice := testResourceSlice(goodName, goodName, driverName)
|
||||
slice.ResourceModel = resource.ResourceModel{}
|
||||
return slice
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
for name, scenario := range scenarios {
|
||||
@@ -228,18 +233,26 @@ func TestValidateResourceSliceUpdate(t *testing.T) {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("metadata", "name"), name+"-update", "field is immutable")},
|
||||
},
|
||||
"invalid-update-nodename": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("nodeName"), name+"-updated", "field is immutable")},
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec", "nodeName"), name+"-updated", "field is immutable")},
|
||||
oldResourceSlice: validResourceSlice,
|
||||
update: func(slice *resource.ResourceSlice) *resource.ResourceSlice {
|
||||
slice.NodeName += "-updated"
|
||||
slice.Spec.NodeName += "-updated"
|
||||
return slice
|
||||
},
|
||||
},
|
||||
"invalid-update-drivername": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("driverName"), name+"-updated", "field is immutable")},
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec", "driver"), name+"-updated", "field is immutable")},
|
||||
oldResourceSlice: validResourceSlice,
|
||||
update: func(slice *resource.ResourceSlice) *resource.ResourceSlice {
|
||||
slice.DriverName += "-updated"
|
||||
slice.Spec.Driver += "-updated"
|
||||
return slice
|
||||
},
|
||||
},
|
||||
"invalid-update-pool": {
|
||||
wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec", "pool", "name"), validResourceSlice.Spec.Pool.Name+"-updated", "field is immutable")},
|
||||
oldResourceSlice: validResourceSlice,
|
||||
update: func(slice *resource.ResourceSlice) *resource.ResourceSlice {
|
||||
slice.Spec.Pool.Name += "-updated"
|
||||
return slice
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user