dra api: implement semver attribute value type

This adds support for semantic version comparison to the CEL support in the
"named resources" structured parameter model. For example, it can be used to
check that an instance supports a certain API level.

To minimize the risk, the new "semver" type is only defined in the CEL
environment for DRA expressions, not in the base library. See
https://github.com/kubernetes/kubernetes/pull/123664 for a PR which
adds it to the base library.

Validation of semver strings is done with the regular expression from
semver.org. The actual evaluation at runtime then uses semver/v4.
This commit is contained in:
Patrick Ohly 2024-03-04 09:13:19 +01:00
parent 234dc1f63d
commit 42ee56f093
25 changed files with 891 additions and 194 deletions

View File

@ -57,6 +57,7 @@ API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttri
API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,QuantityValue
API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,StringSliceValue
API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,StringValue
API rule violation: names_match,k8s.io/api/resource/v1alpha2,NamedResourcesAttributeValue,VersionValue
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Ref
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,Schema
API rule violation: names_match,k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1,JSONSchemaProps,XEmbeddedResource

View File

@ -14900,6 +14900,10 @@
"stringSlice": {
"$ref": "#/definitions/io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice",
"description": "StringSliceValue is an array of strings."
},
"version": {
"description": "VersionValue is a semantic version according to semver.org spec 2.0.0.",
"type": "string"
}
},
"required": [

View File

@ -228,6 +228,10 @@
}
],
"description": "StringSliceValue is an array of strings."
},
"version": {
"description": "VersionValue is a semantic version according to semver.org spec 2.0.0.",
"type": "string"
}
},
"required": [

View File

@ -59,7 +59,8 @@ type NamedResourcesAttributeValue struct {
StringValue *string
// StringSliceValue is an array of strings.
StringSliceValue *NamedResourcesStringSlice
// TODO: VersionValue *SemVersion
// VersionValue is a semantic version according to semver.org spec 2.0.0.
VersionValue *string
}
// NamedResourcesIntSlice contains a slice of 64-bit integers.
@ -74,17 +75,6 @@ type NamedResourcesStringSlice struct {
Strings []string
}
// TODO
//
// A wrapper around https://pkg.go.dev/github.com/blang/semver/v4#Version which
// is encoded as a string. During decoding, it validates that the string
// can be parsed using tolerant parsing (currently trims spaces, removes a "v" prefix,
// adds a 0 patch number to versions with only major and minor components specified,
// and removes leading 0s).
// type SemVersion struct {
// semver.Version
//}
// NamedResourcesRequest is used in ResourceRequestModel.
type NamedResourcesRequest struct {
// Selector is a CEL expression which must evaluate to true if a

View File

@ -18,6 +18,7 @@ package validation
import (
"fmt"
"regexp"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field"
@ -63,6 +64,27 @@ func validateInstances(instances []resource.NamedResourcesInstance, fldPath *fie
return allErrs
}
var (
numericIdentifier = `(0|[1-9]\d*)`
preReleaseIdentifier = `(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)`
buildIdentifier = `[0-9a-zA-Z-]+`
semverRe = regexp.MustCompile(`^` +
// dot-separated version segments (e.g. 1.2.3)
numericIdentifier + `\.` + numericIdentifier + `\.` + numericIdentifier +
// optional dot-separated prerelease segments (e.g. -alpha.PRERELEASE.1)
`(-` + preReleaseIdentifier + `(\.` + preReleaseIdentifier + `)*)?` +
// optional dot-separated build identifier segments (e.g. +build.id.20240305)
`(\+` + buildIdentifier + `(\.` + buildIdentifier + `)*)?` +
`$`)
)
func validateAttributes(attributes []resource.NamedResourcesAttribute, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
attributeNames := sets.New[string]()
@ -95,7 +117,12 @@ func validateAttributes(attributes []resource.NamedResourcesAttribute, fldPath *
if attribute.StringSliceValue != nil {
entries.Insert("stringSlice")
}
// TODO: VersionValue
if attribute.VersionValue != nil {
entries.Insert("version")
if !semverRe.MatchString(*attribute.VersionValue) {
allErrs = append(allErrs, field.Invalid(idxPath.Child("version"), *attribute.VersionValue, "must be a string compatible with semver.org spec 2.0.0"))
}
}
switch len(entries) {
case 0:

View File

@ -75,7 +75,44 @@ func TestValidateResources(t *testing.T) {
"string-slice": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{StringSliceValue: &resourceapi.NamedResourcesStringSlice{Strings: []string{"hello"}}}}}}}),
},
// TODO: semver
"version-okay": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0")}}}}}),
},
"version-beta": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0-beta")}}}}}),
},
"version-beta-1": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0-beta.1")}}}}}),
},
"version-build": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0+build")}}}}}),
},
"version-build-1": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0+build.1")}}}}}),
},
"version-beta-1-build-1": {
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.0-beta.1+build.1")}}}}}),
},
"version-bad": {
wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "1.0", "must be a string compatible with semver.org spec 2.0.0")},
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0")}}}}}),
},
"version-bad-leading-zeros": {
wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "01.0.0", "must be a string compatible with semver.org spec 2.0.0")},
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("01.0.0")}}}}}),
},
"version-bad-leading-zeros-middle": {
wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "1.00.0", "must be a string compatible with semver.org spec 2.0.0")},
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.00.0")}}}}}),
},
"version-bad-leading-zeros-end": {
wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), "1.0.00", "must be a string compatible with semver.org spec 2.0.0")},
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To("1.0.00")}}}}}),
},
"version-bad-spaces": {
wantFailures: field.ErrorList{field.Invalid(field.NewPath("instances").Index(0).Child("attributes").Index(0).Child("version"), " 1.0.0 ", "must be a string compatible with semver.org spec 2.0.0")},
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName, NamedResourcesAttributeValue: resourceapi.NamedResourcesAttributeValue{VersionValue: ptr.To(" 1.0.0 ")}}}}}),
},
"empty-attribute": {
wantFailures: field.ErrorList{field.Required(field.NewPath("instances").Index(0).Child("attributes").Index(0), "exactly one value must be set")},
resources: testResources([]resourceapi.NamedResourcesInstance{{Name: goodName, Attributes: []resourceapi.NamedResourcesAttribute{{Name: goodName}}}}),
@ -132,7 +169,9 @@ func TestValidateSelector(t *testing.T) {
"stringslice": {
selector: `attributes.stringslice["name"].isSorted()`,
},
// TODO: semver
"version": {
selector: `attributes.version["name"].isGreaterThan(semver("1.0.0"))`,
},
}
for name, scenario := range scenarios {

View File

@ -679,6 +679,7 @@ func autoConvert_v1alpha2_NamedResourcesAttributeValue_To_resource_NamedResource
out.IntSliceValue = (*resource.NamedResourcesIntSlice)(unsafe.Pointer(in.IntSliceValue))
out.StringValue = (*string)(unsafe.Pointer(in.StringValue))
out.StringSliceValue = (*resource.NamedResourcesStringSlice)(unsafe.Pointer(in.StringSliceValue))
out.VersionValue = (*string)(unsafe.Pointer(in.VersionValue))
return nil
}
@ -694,6 +695,7 @@ func autoConvert_resource_NamedResourcesAttributeValue_To_v1alpha2_NamedResource
out.IntSliceValue = (*v1alpha2.NamedResourcesIntSlice)(unsafe.Pointer(in.IntSliceValue))
out.StringValue = (*string)(unsafe.Pointer(in.StringValue))
out.StringSliceValue = (*v1alpha2.NamedResourcesStringSlice)(unsafe.Pointer(in.StringSliceValue))
out.VersionValue = (*string)(unsafe.Pointer(in.VersionValue))
return nil
}

View File

@ -187,6 +187,11 @@ func (in *NamedResourcesAttributeValue) DeepCopyInto(out *NamedResourcesAttribut
*out = new(NamedResourcesStringSlice)
(*in).DeepCopyInto(*out)
}
if in.VersionValue != nil {
in, out := &in.VersionValue, &out.VersionValue
*out = new(string)
**out = **in
}
return
}

View File

@ -44907,6 +44907,13 @@ func schema_k8sio_api_resource_v1alpha2_NamedResourcesAttribute(ref common.Refer
Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice"),
},
},
"version": {
SchemaProps: spec.SchemaProps{
Description: "VersionValue is a semantic version according to semver.org spec 2.0.0.",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"name"},
},
@ -44962,6 +44969,13 @@ func schema_k8sio_api_resource_v1alpha2_NamedResourcesAttributeValue(ref common.
Ref: ref("k8s.io/api/resource/v1alpha2.NamedResourcesStringSlice"),
},
},
"version": {
SchemaProps: spec.SchemaProps{
Description: "VersionValue is a semantic version according to semver.org spec 2.0.0.",
Type: []string{"string"},
Format: "",
},
},
},
},
},

View File

@ -1331,147 +1331,149 @@ func init() {
}
var fileDescriptor_4312f5b44a31ec02 = []byte{
// 2231 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x1a, 0x4b, 0x6f, 0x1b, 0xc7,
0xd9, 0x4b, 0xd2, 0x16, 0xf5, 0xc9, 0xa2, 0xa4, 0xb5, 0x64, 0xd1, 0x8e, 0x42, 0x2a, 0x8b, 0x16,
0x15, 0x50, 0x9b, 0x8c, 0xe5, 0xc4, 0x31, 0xd2, 0xb4, 0x80, 0xd7, 0x8a, 0x5d, 0xa1, 0x89, 0xa3,
0x0c, 0x63, 0x27, 0x4e, 0x5f, 0x59, 0x71, 0xc7, 0xd2, 0xd6, 0xe4, 0x2e, 0xbd, 0x33, 0x54, 0x6c,
0xf4, 0x62, 0x14, 0x7d, 0x5d, 0x0a, 0xa4, 0x68, 0x51, 0xb4, 0xa7, 0x9e, 0x8a, 0xa2, 0x97, 0x5e,
0xda, 0x7b, 0x0f, 0x41, 0x1b, 0x03, 0xbd, 0x38, 0x68, 0x81, 0x06, 0x3d, 0x10, 0x35, 0xfb, 0x13,
0x7a, 0xcb, 0xa9, 0x98, 0xc7, 0x3e, 0x66, 0xb9, 0x4b, 0x71, 0xd9, 0x46, 0x48, 0x4e, 0xd2, 0xce,
0x7c, 0xef, 0xef, 0x9b, 0xef, 0x31, 0x43, 0x38, 0x77, 0xf7, 0x32, 0x69, 0x38, 0x5e, 0xd3, 0xea,
0x39, 0x4d, 0x1f, 0x13, 0xaf, 0xef, 0xb7, 0x71, 0xf3, 0xe0, 0x82, 0xd5, 0xe9, 0xed, 0x5b, 0x9b,
0xcd, 0x3d, 0xec, 0x62, 0xdf, 0xa2, 0xd8, 0x6e, 0xf4, 0x7c, 0x8f, 0x7a, 0xfa, 0x9a, 0x80, 0x6e,
0x58, 0x3d, 0xa7, 0x11, 0x40, 0x37, 0x02, 0xe8, 0xb3, 0xe7, 0xf7, 0x1c, 0xba, 0xdf, 0xdf, 0x6d,
0xb4, 0xbd, 0x6e, 0x73, 0xcf, 0xdb, 0xf3, 0x9a, 0x1c, 0x69, 0xb7, 0x7f, 0x87, 0x7f, 0xf1, 0x0f,
0xfe, 0x9f, 0x20, 0x76, 0xd6, 0x88, 0xb1, 0x6e, 0x7b, 0x3e, 0x63, 0x9b, 0x64, 0x78, 0xf6, 0xb9,
0x08, 0xa6, 0x6b, 0xb5, 0xf7, 0x1d, 0x17, 0xfb, 0x0f, 0x9a, 0xbd, 0xbb, 0x7b, 0xaa, 0xbc, 0x79,
0xb0, 0x48, 0xb3, 0x8b, 0xa9, 0x95, 0xc6, 0xab, 0x99, 0x85, 0xe5, 0xf7, 0x5d, 0xea, 0x74, 0x47,
0xd9, 0x5c, 0x3a, 0x0c, 0x81, 0xb4, 0xf7, 0x71, 0xd7, 0x4a, 0xe2, 0x19, 0xbf, 0x2c, 0xc0, 0xe2,
0x95, 0x4e, 0xc7, 0x6b, 0x5b, 0xd4, 0xf1, 0x5c, 0x84, 0x49, 0xbf, 0x43, 0x75, 0x0f, 0x16, 0x02,
0x7d, 0xbe, 0x6a, 0xb9, 0x76, 0x07, 0x93, 0xaa, 0xb6, 0x5e, 0xdc, 0x98, 0xdb, 0x3c, 0xd7, 0x18,
0x67, 0xf4, 0x06, 0x52, 0x90, 0xcc, 0xd5, 0x47, 0x83, 0xfa, 0xb1, 0xe1, 0xa0, 0xbe, 0xa0, 0xae,
0x13, 0x94, 0xa4, 0xae, 0xef, 0xc2, 0xa2, 0x75, 0x60, 0x39, 0x1d, 0x6b, 0xb7, 0x83, 0x5f, 0x73,
0x6f, 0x78, 0x36, 0x26, 0xd5, 0xc2, 0xba, 0xb6, 0x31, 0xb7, 0xb9, 0x1e, 0xe7, 0xc8, 0x3c, 0xd3,
0x38, 0xb8, 0xd0, 0x60, 0x00, 0x2d, 0xdc, 0xc1, 0x6d, 0xea, 0xf9, 0xe6, 0xf2, 0x70, 0x50, 0x5f,
0xbc, 0x92, 0xc0, 0x46, 0x23, 0xf4, 0xf4, 0x26, 0xcc, 0x92, 0x7d, 0xcb, 0xc7, 0x6c, 0xad, 0x5a,
0x5c, 0xd7, 0x36, 0xca, 0xe6, 0x92, 0x14, 0x70, 0xb6, 0x15, 0x6c, 0xa0, 0x08, 0xc6, 0xf8, 0xa9,
0x06, 0x2b, 0x49, 0xd3, 0xbc, 0xea, 0xd9, 0xb8, 0xa3, 0xdf, 0x87, 0x8a, 0x6b, 0x75, 0xb1, 0x1d,
0xe8, 0xc5, 0xcc, 0xc3, 0x84, 0x7d, 0x69, 0xbc, 0x79, 0x6e, 0x28, 0x38, 0x49, 0xd2, 0xa6, 0x3e,
0x1c, 0xd4, 0x2b, 0x2a, 0x0c, 0x4a, 0xf0, 0x31, 0x7e, 0x5f, 0x80, 0xd3, 0x5b, 0xbe, 0x73, 0x80,
0xfd, 0x11, 0xa7, 0xfd, 0x58, 0x83, 0xd5, 0x03, 0xec, 0xda, 0x9e, 0x8f, 0xf0, 0xbd, 0x3e, 0x26,
0x74, 0xc7, 0xf2, 0xad, 0x2e, 0xa6, 0xd8, 0x0f, 0xc4, 0x3b, 0x1f, 0x13, 0x2f, 0x0c, 0x92, 0x46,
0xef, 0xee, 0x5e, 0x43, 0x06, 0x49, 0x03, 0x59, 0xef, 0xbe, 0x7c, 0x9f, 0x62, 0x97, 0x38, 0x9e,
0x6b, 0xd6, 0xa5, 0x75, 0x56, 0x6f, 0xa5, 0x53, 0x45, 0x59, 0xec, 0x98, 0x28, 0x2b, 0x56, 0x9a,
0xe5, 0xa4, 0x53, 0x2f, 0x8e, 0xb7, 0x53, 0xaa, 0xd1, 0xcd, 0xa7, 0xa5, 0x38, 0xe9, 0x3e, 0x41,
0xe9, 0x0c, 0x8d, 0x5f, 0x14, 0xa0, 0x22, 0x0c, 0x26, 0xc5, 0x24, 0xfa, 0x26, 0x80, 0xcd, 0x57,
0x98, 0xad, 0xb9, 0x69, 0x66, 0x4d, 0x5d, 0x12, 0x87, 0xad, 0x70, 0x07, 0xc5, 0xa0, 0x74, 0x02,
0x8b, 0x42, 0xd9, 0x98, 0x51, 0x0b, 0xd3, 0x18, 0xb5, 0x2a, 0x19, 0x2d, 0xde, 0x4a, 0x90, 0x43,
0x23, 0x0c, 0xf4, 0xaf, 0x43, 0xd9, 0x97, 0x42, 0x57, 0x8b, 0xfc, 0xfc, 0x9d, 0x9f, 0xec, 0xfc,
0x49, 0x55, 0xcd, 0x45, 0xc9, 0xac, 0x1c, 0xe8, 0x8e, 0x42, 0x82, 0x86, 0x09, 0xb5, 0xf1, 0xf1,
0xa8, 0xaf, 0x43, 0xc9, 0x8d, 0x2c, 0x74, 0x52, 0xd2, 0x2a, 0x71, 0xdb, 0xf0, 0x1d, 0xe3, 0x2f,
0x1a, 0xac, 0x26, 0x88, 0x50, 0xea, 0x3b, 0xbb, 0x7d, 0x8a, 0x0f, 0xc7, 0x66, 0x51, 0x52, 0xb1,
0x02, 0xf8, 0x5b, 0x56, 0xa7, 0x8f, 0xa5, 0x49, 0x5f, 0xcc, 0x75, 0x8c, 0x14, 0x0a, 0xe6, 0xe7,
0x24, 0xa3, 0xb5, 0x71, 0x50, 0x28, 0xc1, 0xd7, 0xf8, 0x53, 0x11, 0xc6, 0x22, 0xe8, 0xdf, 0x84,
0xf2, 0xbd, 0xbe, 0xe5, 0x52, 0x87, 0x3e, 0xa8, 0x9e, 0xe0, 0x42, 0x36, 0x32, 0xfd, 0xae, 0x48,
0xfd, 0xba, 0xc4, 0x32, 0x97, 0x86, 0x83, 0xfa, 0x7c, 0xf0, 0x25, 0xa4, 0x08, 0x49, 0xea, 0xcf,
0x40, 0x69, 0xd7, 0xf3, 0xc4, 0xf1, 0x28, 0x9b, 0xf3, 0x2c, 0x25, 0x99, 0x9e, 0xd7, 0x11, 0x60,
0x7c, 0x4b, 0xaf, 0x41, 0xd1, 0x71, 0x69, 0x75, 0x66, 0x5d, 0xdb, 0x28, 0x9a, 0x27, 0x99, 0x53,
0xb7, 0x5d, 0x2a, 0x00, 0xd8, 0x86, 0xde, 0x86, 0xb2, 0xe3, 0xd2, 0x56, 0xc7, 0x69, 0xe3, 0x6a,
0x99, 0x4b, 0xf8, 0x5c, 0x1e, 0x33, 0x6e, 0x4b, 0x5c, 0x21, 0x67, 0xf0, 0x25, 0xe5, 0x0c, 0x08,
0xeb, 0x5f, 0x80, 0x13, 0x84, 0xfa, 0x8e, 0xbb, 0x57, 0x3d, 0xce, 0xdd, 0xba, 0x30, 0x1c, 0xd4,
0xe7, 0x5a, 0x7c, 0x45, 0x80, 0xca, 0x6d, 0xdd, 0x83, 0x39, 0xf1, 0x9f, 0x10, 0x68, 0x96, 0x0b,
0xf4, 0x42, 0x1e, 0x81, 0x5a, 0x11, 0xba, 0x48, 0xf1, 0xb1, 0x05, 0xc1, 0x2b, 0xce, 0xc1, 0xd8,
0x82, 0x65, 0x15, 0xff, 0x9a, 0xd3, 0xa1, 0xd8, 0xd7, 0xcf, 0x41, 0x99, 0xc8, 0x4a, 0x21, 0x43,
0x31, 0x3c, 0x14, 0x41, 0x05, 0x41, 0x21, 0x84, 0xf1, 0x1b, 0x0d, 0x4e, 0x27, 0xed, 0x42, 0xa8,
0xe5, 0xb6, 0x27, 0x89, 0x67, 0x07, 0x20, 0x0c, 0x2b, 0x96, 0x1d, 0xd8, 0x81, 0x7d, 0x7e, 0xaa,
0x50, 0x8e, 0xd2, 0x51, 0xb8, 0x44, 0x50, 0x8c, 0xb8, 0x71, 0x69, 0x54, 0x4c, 0xe9, 0xa1, 0x35,
0x28, 0x39, 0x2e, 0x15, 0xf5, 0xba, 0x68, 0x96, 0x99, 0x88, 0xdb, 0x2e, 0x25, 0x88, 0xaf, 0x1a,
0x2f, 0xc3, 0x4a, 0xa2, 0xc0, 0x88, 0x74, 0x90, 0xd3, 0x4c, 0x0f, 0x47, 0xce, 0x7d, 0xf8, 0x8f,
0x8e, 0x61, 0xd6, 0x91, 0x36, 0x0b, 0xba, 0x86, 0x9c, 0x81, 0x28, 0x90, 0xa3, 0xe2, 0x1c, 0xac,
0x10, 0x14, 0x51, 0x36, 0x4c, 0x38, 0x93, 0x19, 0x2f, 0xfa, 0xe7, 0x61, 0x46, 0xc4, 0x86, 0x90,
0x60, 0xd6, 0x9c, 0x1b, 0x0e, 0xea, 0x33, 0x02, 0x82, 0xa0, 0x60, 0xcf, 0xf8, 0xa1, 0x06, 0x4b,
0xac, 0x37, 0x08, 0x68, 0x88, 0xe2, 0x7e, 0x2f, 0xa3, 0xb8, 0xe7, 0x72, 0x65, 0xf8, 0xcf, 0x44,
0x55, 0xfd, 0xc3, 0x82, 0x2a, 0x88, 0xd0, 0xe2, 0x1d, 0x28, 0xb3, 0xf6, 0xd0, 0xb6, 0xa8, 0x25,
0x45, 0x78, 0x76, 0x5c, 0xce, 0x21, 0x0d, 0x06, 0xcd, 0xda, 0xa3, 0xd7, 0x76, 0xbf, 0x83, 0xdb,
0xf4, 0x55, 0x4c, 0xad, 0x28, 0x90, 0xa2, 0x35, 0x14, 0x52, 0x65, 0x5e, 0x77, 0x3d, 0x1b, 0xf3,
0x3a, 0x58, 0x50, 0xbd, 0x7e, 0x43, 0xae, 0xa3, 0x10, 0x22, 0x51, 0x37, 0x8b, 0x13, 0xd5, 0xcd,
0xfb, 0xb0, 0xe4, 0x26, 0x2d, 0x5c, 0x2d, 0x71, 0x65, 0x9a, 0x87, 0xd8, 0x33, 0x89, 0x66, 0x9e,
0x91, 0xbc, 0x46, 0x7d, 0x86, 0x46, 0x99, 0x18, 0x7f, 0xd5, 0x60, 0x65, 0xc4, 0xa6, 0xaf, 0x38,
0x84, 0xea, 0xdf, 0x18, 0xb1, 0x6b, 0x63, 0x32, 0xbb, 0x32, 0x6c, 0x6e, 0xd5, 0xd0, 0x4a, 0xc1,
0x4a, 0xcc, 0xa6, 0x6f, 0xc0, 0x71, 0x87, 0xe2, 0x6e, 0x90, 0x00, 0x72, 0x68, 0x29, 0x72, 0xdd,
0xbc, 0xa4, 0x7d, 0x7c, 0x9b, 0x51, 0x41, 0x82, 0x98, 0xf1, 0xc7, 0x02, 0x2c, 0xef, 0x78, 0x76,
0xab, 0xbd, 0x8f, 0xed, 0x7e, 0xc7, 0x71, 0xf7, 0xae, 0x7a, 0x2e, 0xc5, 0xf7, 0xe9, 0x11, 0x04,
0xc9, 0x5b, 0x50, 0x22, 0x3d, 0xdc, 0x96, 0xb5, 0xf9, 0xd2, 0x78, 0x7d, 0xd2, 0x64, 0x6c, 0xf5,
0x70, 0x3b, 0x4a, 0x98, 0xec, 0x0b, 0x71, 0x8a, 0xfa, 0x3b, 0xac, 0x9a, 0x58, 0xb4, 0x4f, 0x78,
0x30, 0xcd, 0x6d, 0x5e, 0x9e, 0x82, 0x36, 0xc7, 0x37, 0x2b, 0x92, 0xfa, 0x09, 0xf1, 0x8d, 0x24,
0x5d, 0xe3, 0x43, 0x0d, 0xaa, 0x69, 0x68, 0x47, 0x10, 0x07, 0x6f, 0xaa, 0x71, 0xb0, 0x99, 0x5f,
0xb7, 0x8c, 0x50, 0x78, 0x2f, 0x43, 0x27, 0x66, 0x58, 0xfd, 0x32, 0x9c, 0x14, 0x59, 0x1a, 0xdb,
0x2c, 0xb4, 0x64, 0x2e, 0x5f, 0x96, 0x84, 0x4e, 0xb6, 0x62, 0x7b, 0x48, 0x81, 0xd4, 0x5f, 0x84,
0x4a, 0xcf, 0xa3, 0xd8, 0xa5, 0x8e, 0xd5, 0x09, 0x06, 0x30, 0x96, 0x3a, 0x79, 0xfe, 0xda, 0x51,
0x76, 0x50, 0x02, 0xd2, 0xf8, 0x95, 0x06, 0x67, 0xb3, 0xbd, 0xa3, 0x7f, 0x17, 0x2a, 0x81, 0xc6,
0x57, 0x3b, 0x96, 0xd3, 0x0d, 0xea, 0xc2, 0x97, 0x26, 0xeb, 0x66, 0x39, 0x4e, 0x44, 0x5b, 0xba,
0xfc, 0xb4, 0xd4, 0xa9, 0xa2, 0x80, 0x11, 0x94, 0x60, 0x65, 0xfc, 0xba, 0x00, 0xf3, 0x0a, 0xc8,
0x11, 0x1c, 0x99, 0xd7, 0x95, 0x23, 0xd3, 0xcc, 0xa3, 0x66, 0xd6, 0x59, 0xb9, 0x9d, 0x38, 0x2b,
0x17, 0xf2, 0x10, 0x1d, 0x7f, 0x48, 0x86, 0x1a, 0xd4, 0x14, 0xf8, 0xab, 0x9e, 0x4b, 0xfa, 0x5d,
0x36, 0x31, 0xdd, 0xc1, 0x3e, 0x66, 0xcd, 0xcf, 0x39, 0x28, 0x5b, 0x3d, 0xe7, 0xba, 0xef, 0xf5,
0x7b, 0xc9, 0xf6, 0xe0, 0xca, 0xce, 0x36, 0x5f, 0x47, 0x21, 0x04, 0x83, 0x0e, 0x24, 0x92, 0x65,
0x22, 0x36, 0x88, 0xc8, 0x09, 0x25, 0x84, 0x08, 0x1b, 0xab, 0x52, 0x66, 0x63, 0x65, 0x42, 0xb1,
0xef, 0xd8, 0xb2, 0xe5, 0x7c, 0x56, 0x02, 0x14, 0x6f, 0x6e, 0x6f, 0x7d, 0x3c, 0xa8, 0x3f, 0x93,
0x75, 0xef, 0x41, 0x1f, 0xf4, 0x30, 0x69, 0xdc, 0xdc, 0xde, 0x42, 0x0c, 0xd9, 0x78, 0x5f, 0x83,
0x25, 0x45, 0xc9, 0x23, 0x48, 0x01, 0x3b, 0x6a, 0x0a, 0xf8, 0x62, 0x0e, 0x97, 0x65, 0x9c, 0xfd,
0x9f, 0x15, 0x61, 0x55, 0x81, 0x8b, 0x4d, 0x8b, 0x9f, 0x7c, 0x58, 0xbf, 0x0b, 0xf3, 0xe1, 0xf5,
0xd1, 0x35, 0xdf, 0xeb, 0xca, 0xf8, 0xfe, 0x4a, 0x0e, 0xbd, 0x62, 0xf3, 0x6e, 0x10, 0x5c, 0x62,
0xe2, 0xb8, 0x1e, 0x27, 0x8c, 0x54, 0x3e, 0xb9, 0xaf, 0x6e, 0xf4, 0x0e, 0x54, 0x6c, 0x65, 0xe8,
0xaf, 0x96, 0x26, 0xb9, 0xbf, 0x52, 0x2f, 0x0a, 0xa2, 0x14, 0xa3, 0xae, 0xa3, 0x04, 0x6d, 0xe3,
0x1f, 0x1a, 0x3c, 0x95, 0xa1, 0xe5, 0x11, 0x44, 0xd9, 0xdb, 0x6a, 0x94, 0x3d, 0x3f, 0x95, 0x37,
0x32, 0xe2, 0xed, 0xe7, 0x1a, 0xac, 0x1f, 0xe6, 0xbf, 0x9c, 0xc9, 0x61, 0x1d, 0x4a, 0x77, 0x1d,
0xd7, 0x96, 0xfd, 0x66, 0x78, 0xdc, 0xbf, 0xe6, 0xb8, 0x36, 0xe2, 0x3b, 0x61, 0x42, 0x28, 0x66,
0xde, 0x3b, 0x3c, 0xd4, 0xe0, 0xe9, 0xb1, 0xd5, 0x61, 0x82, 0x69, 0xed, 0xcb, 0xb0, 0xd0, 0x77,
0x49, 0xdf, 0xa1, 0x2c, 0x60, 0xe2, 0x05, 0xef, 0xd4, 0x70, 0x50, 0x5f, 0xb8, 0xa9, 0x6e, 0xa1,
0x24, 0xac, 0xf1, 0xdb, 0x42, 0x22, 0x9f, 0xf0, 0xf2, 0x7b, 0x1d, 0x96, 0x62, 0xe5, 0x87, 0x90,
0xd8, 0x0d, 0x53, 0xd8, 0xbd, 0xa2, 0x24, 0x00, 0x1a, 0xc5, 0x61, 0x47, 0xad, 0x17, 0x37, 0xf5,
0xff, 0xf3, 0xa8, 0x29, 0x1b, 0x48, 0xe5, 0xa3, 0xef, 0x40, 0x25, 0xba, 0x48, 0x63, 0x9d, 0xb4,
0x74, 0xc3, 0x46, 0x70, 0x16, 0xae, 0x28, 0xbb, 0x1f, 0x8f, 0xac, 0xa0, 0x04, 0xbe, 0xf1, 0x9f,
0x02, 0x9c, 0x4a, 0x29, 0x47, 0x53, 0x5d, 0xc3, 0x7d, 0x0b, 0x20, 0xa2, 0x2e, 0x6d, 0xd2, 0xc8,
0x77, 0x99, 0x68, 0x56, 0xf8, 0x5c, 0x1d, 0xad, 0xc6, 0x28, 0xea, 0x04, 0xe6, 0x7c, 0x4c, 0xb0,
0x7f, 0x80, 0xed, 0x6b, 0x9e, 0x2f, 0x2f, 0xdd, 0x5e, 0xca, 0x61, 0xf4, 0x91, 0xd2, 0x69, 0x9e,
0x92, 0x2a, 0xcd, 0xa1, 0x88, 0x30, 0x8a, 0x73, 0xd1, 0x5b, 0xb0, 0x62, 0xe3, 0xf8, 0xed, 0x25,
0x4f, 0x2b, 0xd8, 0xe6, 0x15, 0xb1, 0x1c, 0xdd, 0x7b, 0x6e, 0xa5, 0x01, 0xa1, 0x74, 0x5c, 0xe3,
0xef, 0x1a, 0xac, 0x28, 0x92, 0xbd, 0x81, 0xbb, 0xbd, 0x8e, 0x45, 0x8f, 0x62, 0xac, 0xbc, 0xad,
0xb4, 0x3f, 0x2f, 0xe4, 0x30, 0x5f, 0x20, 0x64, 0x56, 0x1b, 0x64, 0xfc, 0x4d, 0x83, 0x33, 0xa9,
0x18, 0x47, 0x90, 0x68, 0xdf, 0x52, 0x13, 0xed, 0xc5, 0x29, 0xf4, 0xca, 0x48, 0xb3, 0x8f, 0xb3,
0xb4, 0x6a, 0x89, 0x31, 0xe9, 0xb3, 0xd7, 0xaf, 0x1a, 0x1f, 0x14, 0x95, 0xb6, 0x9b, 0x1c, 0x45,
0x7f, 0xa2, 0x66, 0x94, 0xc2, 0x44, 0x19, 0x65, 0x24, 0xd1, 0x16, 0x73, 0x26, 0x5a, 0x42, 0xa6,
0x4b, 0xb4, 0xb7, 0x61, 0x5e, 0xad, 0x3e, 0xa5, 0x09, 0xdf, 0xbb, 0x38, 0xe9, 0x96, 0x52, 0x9d,
0x54, 0x4a, 0xfa, 0x2b, 0xb0, 0x4c, 0xa8, 0xdf, 0x6f, 0xd3, 0xbe, 0x8f, 0xed, 0xd8, 0x83, 0xc5,
0x71, 0x9e, 0x4f, 0xaa, 0xc3, 0x41, 0x7d, 0xb9, 0x95, 0xb2, 0x8f, 0x52, 0xb1, 0x92, 0x9d, 0x33,
0x21, 0x9f, 0xe6, 0xce, 0x99, 0x64, 0x75, 0x32, 0xef, 0xab, 0x9d, 0x73, 0xdc, 0x6b, 0x9f, 0x85,
0xce, 0x79, 0x4c, 0x94, 0x8d, 0xed, 0x9c, 0x69, 0xca, 0xbb, 0x95, 0xa8, 0x6a, 0x87, 0x94, 0xcd,
0xe4, 0xf3, 0x54, 0xae, 0x87, 0xab, 0x37, 0x61, 0xe6, 0x0e, 0xbf, 0x7e, 0x9f, 0xb0, 0xef, 0x0e,
0x14, 0x15, 0x77, 0xf6, 0xe6, 0x82, 0x64, 0x35, 0x23, 0xbe, 0x09, 0x0a, 0xa8, 0x25, 0x3b, 0xed,
0xb8, 0x55, 0x3e, 0xcd, 0x9d, 0x76, 0x5c, 0xce, 0x8c, 0xf8, 0xfc, 0xb3, 0xda, 0x69, 0xa7, 0xfa,
0xfb, 0xe8, 0x3b, 0x6d, 0x36, 0x79, 0xb1, 0xbf, 0xa4, 0x67, 0xb5, 0x83, 0x09, 0x3d, 0x9c, 0xbc,
0x6e, 0x04, 0x1b, 0x28, 0x82, 0x31, 0x3e, 0xd0, 0xa0, 0xa2, 0xba, 0x73, 0xaa, 0x46, 0xef, 0xa1,
0x06, 0xa7, 0x7c, 0x85, 0x4c, 0xfc, 0xfd, 0xf8, 0x42, 0x9e, 0x70, 0x12, 0x97, 0xc7, 0x4f, 0x49,
0x86, 0xa7, 0x52, 0x36, 0x51, 0x1a, 0x2b, 0xe3, 0x07, 0x1a, 0xa4, 0x01, 0xeb, 0x6e, 0xc6, 0xfb,
0xc0, 0x66, 0x9e, 0xf7, 0x01, 0x19, 0xe9, 0x93, 0x3c, 0x0e, 0xfc, 0x33, 0x66, 0x51, 0xf1, 0x7b,
0x89, 0xa9, 0x2c, 0xba, 0x0e, 0x25, 0x7e, 0x2c, 0x12, 0xd1, 0xb0, 0x65, 0x51, 0x0b, 0xf1, 0x1d,
0xdd, 0x87, 0x4a, 0x54, 0x00, 0xd8, 0x3a, 0x2f, 0x18, 0x87, 0x5e, 0xf9, 0x46, 0xa5, 0x24, 0xf1,
0xf3, 0x0f, 0xae, 0x5c, 0x4b, 0xa1, 0x88, 0x12, 0x1c, 0x8c, 0x9f, 0x14, 0x60, 0x21, 0xf1, 0x6a,
0x9d, 0xfa, 0xd6, 0xae, 0x7d, 0xd2, 0x6f, 0xed, 0xdf, 0xd7, 0x60, 0xd9, 0x57, 0x05, 0x89, 0x47,
0xdc, 0x66, 0xae, 0x87, 0x77, 0x11, 0x72, 0x6b, 0x92, 0xfd, 0x72, 0xda, 0x2e, 0x4a, 0xe5, 0x66,
0xfc, 0x48, 0x83, 0x54, 0x70, 0xdd, 0xcb, 0x88, 0xba, 0x8b, 0xf9, 0x5e, 0xa5, 0xc4, 0xef, 0x02,
0x26, 0x09, 0xbb, 0x3f, 0x14, 0xa1, 0x9a, 0xe5, 0x5a, 0xfd, 0x7b, 0x1a, 0xac, 0x08, 0x13, 0x26,
0x72, 0xd5, 0x74, 0x8e, 0x0a, 0x47, 0x9c, 0x5b, 0x69, 0x34, 0x51, 0x3a, 0x2b, 0x55, 0x88, 0xf8,
0xbc, 0x3b, 0xdd, 0x2f, 0x33, 0x46, 0x85, 0x50, 0x66, 0xe8, 0x74, 0x56, 0xca, 0x13, 0x5a, 0xe9,
0xd0, 0x27, 0xb4, 0x6f, 0xc3, 0x8c, 0xcf, 0xa7, 0x50, 0xd6, 0x8c, 0x4d, 0xf0, 0x34, 0x9a, 0xfe,
0x53, 0x9f, 0xa8, 0x40, 0x8a, 0x6f, 0x82, 0x02, 0xaa, 0xc6, 0xef, 0x34, 0x18, 0x89, 0xf6, 0xa9,
0xd2, 0x85, 0x05, 0xd0, 0xfb, 0x1f, 0x0d, 0x1a, 0xb2, 0x88, 0x59, 0x31, 0x46, 0xd4, 0x34, 0x1f,
0x3d, 0xa9, 0x1d, 0x7b, 0xfc, 0xa4, 0x76, 0xec, 0xa3, 0x27, 0xb5, 0x63, 0x0f, 0x87, 0x35, 0xed,
0xd1, 0xb0, 0xa6, 0x3d, 0x1e, 0xd6, 0xb4, 0x8f, 0x86, 0x35, 0xed, 0x5f, 0xc3, 0x9a, 0xf6, 0xde,
0xbf, 0x6b, 0xc7, 0xde, 0x5e, 0x1b, 0xf7, 0xa3, 0xc0, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x15,
0x38, 0x05, 0x05, 0x33, 0x28, 0x00, 0x00,
// 2257 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0xcd, 0x6f, 0x1b, 0xc7,
0xf5, 0x5e, 0x92, 0xb6, 0xa8, 0x27, 0x8b, 0x92, 0xd6, 0x92, 0x4d, 0x3b, 0x0a, 0xa9, 0x2c, 0x7e,
0x3f, 0x54, 0x68, 0x6d, 0x32, 0x96, 0x13, 0xc7, 0x48, 0xd3, 0x02, 0x5e, 0x2b, 0x76, 0x85, 0x26,
0x8e, 0x32, 0x8c, 0x95, 0x38, 0xfd, 0xca, 0x8a, 0x3b, 0x96, 0xb6, 0x26, 0x77, 0xe9, 0x9d, 0xa1,
0x62, 0xa3, 0x17, 0xa3, 0xe8, 0xd7, 0xa5, 0x40, 0x8a, 0x16, 0x45, 0x7b, 0xea, 0xa9, 0x28, 0x7a,
0xe9, 0xa5, 0xfd, 0x0f, 0x82, 0x36, 0x06, 0x7a, 0x71, 0xd0, 0x02, 0x0d, 0x7a, 0x20, 0x6a, 0xf6,
0xd8, 0x63, 0x6f, 0x39, 0x15, 0xf3, 0xb1, 0x1f, 0xb3, 0xdc, 0xa5, 0xb8, 0x6c, 0x23, 0x24, 0x27,
0x72, 0x66, 0xde, 0xf7, 0x7b, 0xf3, 0xde, 0x9b, 0x99, 0x85, 0xf3, 0x77, 0xaf, 0x90, 0x86, 0xe3,
0x35, 0xad, 0x9e, 0xd3, 0xf4, 0x31, 0xf1, 0xfa, 0x7e, 0x1b, 0x37, 0x0f, 0x2e, 0x5a, 0x9d, 0xde,
0xbe, 0xb5, 0xd1, 0xdc, 0xc3, 0x2e, 0xf6, 0x2d, 0x8a, 0xed, 0x46, 0xcf, 0xf7, 0xa8, 0xa7, 0xaf,
0x0a, 0xe8, 0x86, 0xd5, 0x73, 0x1a, 0x01, 0x74, 0x23, 0x80, 0x3e, 0x77, 0x61, 0xcf, 0xa1, 0xfb,
0xfd, 0xdd, 0x46, 0xdb, 0xeb, 0x36, 0xf7, 0xbc, 0x3d, 0xaf, 0xc9, 0x91, 0x76, 0xfb, 0x77, 0xf8,
0x88, 0x0f, 0xf8, 0x3f, 0x41, 0xec, 0x9c, 0x11, 0x63, 0xdd, 0xf6, 0x7c, 0xc6, 0x36, 0xc9, 0xf0,
0xdc, 0x73, 0x11, 0x4c, 0xd7, 0x6a, 0xef, 0x3b, 0x2e, 0xf6, 0x1f, 0x34, 0x7b, 0x77, 0xf7, 0x54,
0x79, 0xf3, 0x60, 0x91, 0x66, 0x17, 0x53, 0x2b, 0x8d, 0x57, 0x33, 0x0b, 0xcb, 0xef, 0xbb, 0xd4,
0xe9, 0x8e, 0xb2, 0xb9, 0x7c, 0x18, 0x02, 0x69, 0xef, 0xe3, 0xae, 0x95, 0xc4, 0x33, 0x7e, 0x51,
0x80, 0xc5, 0xab, 0x9d, 0x8e, 0xd7, 0xb6, 0xa8, 0xe3, 0xb9, 0x08, 0x93, 0x7e, 0x87, 0xea, 0x1e,
0x2c, 0x04, 0xfa, 0x7c, 0xc5, 0x72, 0xed, 0x0e, 0x26, 0x55, 0x6d, 0xad, 0xb8, 0x3e, 0xb7, 0x71,
0xbe, 0x31, 0xce, 0xe8, 0x0d, 0xa4, 0x20, 0x99, 0x67, 0x1e, 0x0d, 0xea, 0xc7, 0x86, 0x83, 0xfa,
0x82, 0x3a, 0x4f, 0x50, 0x92, 0xba, 0xbe, 0x0b, 0x8b, 0xd6, 0x81, 0xe5, 0x74, 0xac, 0xdd, 0x0e,
0x7e, 0xcd, 0xbd, 0xe9, 0xd9, 0x98, 0x54, 0x0b, 0x6b, 0xda, 0xfa, 0xdc, 0xc6, 0x5a, 0x9c, 0x23,
0xf3, 0x4c, 0xe3, 0xe0, 0x62, 0x83, 0x01, 0xb4, 0x70, 0x07, 0xb7, 0xa9, 0xe7, 0x9b, 0xcb, 0xc3,
0x41, 0x7d, 0xf1, 0x6a, 0x02, 0x1b, 0x8d, 0xd0, 0xd3, 0x9b, 0x30, 0x4b, 0xf6, 0x2d, 0x1f, 0xb3,
0xb9, 0x6a, 0x71, 0x4d, 0x5b, 0x2f, 0x9b, 0x4b, 0x52, 0xc0, 0xd9, 0x56, 0xb0, 0x80, 0x22, 0x18,
0xe3, 0x27, 0x1a, 0xac, 0x24, 0x4d, 0xf3, 0xaa, 0x67, 0xe3, 0x8e, 0x7e, 0x1f, 0x2a, 0xae, 0xd5,
0xc5, 0x76, 0xa0, 0x17, 0x33, 0x0f, 0x13, 0xf6, 0xa5, 0xf1, 0xe6, 0xb9, 0xa9, 0xe0, 0x24, 0x49,
0x9b, 0xfa, 0x70, 0x50, 0xaf, 0xa8, 0x30, 0x28, 0xc1, 0xc7, 0xf8, 0x5d, 0x01, 0x4e, 0x6f, 0xfa,
0xce, 0x01, 0xf6, 0x47, 0x9c, 0xf6, 0x23, 0x0d, 0xce, 0x1c, 0x60, 0xd7, 0xf6, 0x7c, 0x84, 0xef,
0xf5, 0x31, 0xa1, 0xdb, 0x96, 0x6f, 0x75, 0x31, 0xc5, 0x7e, 0x20, 0xde, 0x85, 0x98, 0x78, 0x61,
0x90, 0x34, 0x7a, 0x77, 0xf7, 0x1a, 0x32, 0x48, 0x1a, 0xc8, 0x7a, 0xf7, 0xe5, 0xfb, 0x14, 0xbb,
0xc4, 0xf1, 0x5c, 0xb3, 0x2e, 0xad, 0x73, 0x66, 0x27, 0x9d, 0x2a, 0xca, 0x62, 0xc7, 0x44, 0x59,
0xb1, 0xd2, 0x2c, 0x27, 0x9d, 0x7a, 0x69, 0xbc, 0x9d, 0x52, 0x8d, 0x6e, 0x3e, 0x2d, 0xc5, 0x49,
0xf7, 0x09, 0x4a, 0x67, 0x68, 0xfc, 0xbc, 0x00, 0x15, 0x61, 0x30, 0x29, 0x26, 0xd1, 0x37, 0x00,
0x6c, 0x3e, 0xc3, 0x6c, 0xcd, 0x4d, 0x33, 0x6b, 0xea, 0x92, 0x38, 0x6c, 0x86, 0x2b, 0x28, 0x06,
0xa5, 0x13, 0x58, 0x14, 0xca, 0xc6, 0x8c, 0x5a, 0x98, 0xc6, 0xa8, 0x55, 0xc9, 0x68, 0x71, 0x27,
0x41, 0x0e, 0x8d, 0x30, 0xd0, 0xbf, 0x06, 0x65, 0x5f, 0x0a, 0x5d, 0x2d, 0xf2, 0xfd, 0x77, 0x61,
0xb2, 0xfd, 0x27, 0x55, 0x35, 0x17, 0x25, 0xb3, 0x72, 0xa0, 0x3b, 0x0a, 0x09, 0x1a, 0x26, 0xd4,
0xc6, 0xc7, 0xa3, 0xbe, 0x06, 0x25, 0x37, 0xb2, 0xd0, 0x49, 0x49, 0xab, 0xc4, 0x6d, 0xc3, 0x57,
0x8c, 0x3f, 0x69, 0x70, 0x26, 0x41, 0x84, 0x52, 0xdf, 0xd9, 0xed, 0x53, 0x7c, 0x38, 0x36, 0x8b,
0x92, 0x8a, 0x15, 0xc0, 0xef, 0x58, 0x9d, 0x3e, 0x96, 0x26, 0x7d, 0x31, 0xd7, 0x36, 0x52, 0x28,
0x98, 0xff, 0x27, 0x19, 0xad, 0x8e, 0x83, 0x42, 0x09, 0xbe, 0xc6, 0xbf, 0x8a, 0x30, 0x16, 0x41,
0xff, 0x06, 0x94, 0xef, 0xf5, 0x2d, 0x97, 0x3a, 0xf4, 0x41, 0xf5, 0x04, 0x17, 0xb2, 0x91, 0xe9,
0x77, 0x45, 0xea, 0xd7, 0x25, 0x96, 0xb9, 0x34, 0x1c, 0xd4, 0xe7, 0x83, 0x91, 0x90, 0x22, 0x24,
0xa9, 0x3f, 0x03, 0xa5, 0x5d, 0xcf, 0x13, 0xdb, 0xa3, 0x6c, 0xce, 0xb3, 0x94, 0x64, 0x7a, 0x5e,
0x47, 0x80, 0xf1, 0x25, 0xbd, 0x06, 0x45, 0xc7, 0xa5, 0xd5, 0x99, 0x35, 0x6d, 0xbd, 0x68, 0x9e,
0x64, 0x4e, 0xdd, 0x72, 0xa9, 0x00, 0x60, 0x0b, 0x7a, 0x1b, 0xca, 0x8e, 0x4b, 0x5b, 0x1d, 0xa7,
0x8d, 0xab, 0x65, 0x2e, 0xe1, 0x73, 0x79, 0xcc, 0xb8, 0x25, 0x71, 0x85, 0x9c, 0xc1, 0x48, 0xca,
0x19, 0x10, 0xd6, 0x3f, 0x07, 0x27, 0x08, 0xf5, 0x1d, 0x77, 0xaf, 0x7a, 0x9c, 0xbb, 0x75, 0x61,
0x38, 0xa8, 0xcf, 0xb5, 0xf8, 0x8c, 0x00, 0x95, 0xcb, 0xba, 0x07, 0x73, 0xe2, 0x9f, 0x10, 0x68,
0x96, 0x0b, 0xf4, 0x42, 0x1e, 0x81, 0x5a, 0x11, 0xba, 0x48, 0xf1, 0xb1, 0x09, 0xc1, 0x2b, 0xce,
0x41, 0xff, 0x3c, 0xcc, 0x1c, 0x60, 0x9f, 0x6d, 0xb1, 0x2a, 0x70, 0xd1, 0x16, 0x87, 0x83, 0xfa,
0xc9, 0x1d, 0x31, 0x25, 0xe0, 0x03, 0x00, 0x63, 0x13, 0x96, 0x55, 0x5e, 0xd7, 0x9d, 0x0e, 0xc5,
0xbe, 0x7e, 0x1e, 0xca, 0x44, 0x56, 0x15, 0x19, 0xb6, 0xe1, 0x06, 0x0a, 0xaa, 0x0d, 0x0a, 0x21,
0x8c, 0x5f, 0x6b, 0x70, 0x3a, 0x69, 0x43, 0x42, 0x2d, 0xb7, 0x3d, 0x49, 0xec, 0x3b, 0x00, 0x61,
0x08, 0xb2, 0x4c, 0xc2, 0x36, 0xf7, 0xf3, 0x53, 0x85, 0x7d, 0x94, 0xba, 0xc2, 0x29, 0x82, 0x62,
0xc4, 0x8d, 0xcb, 0xa3, 0x62, 0x4a, 0x6f, 0xae, 0x42, 0xc9, 0x71, 0xa9, 0xa8, 0xed, 0x45, 0xb3,
0xcc, 0x44, 0xdc, 0x72, 0x29, 0x41, 0x7c, 0xd6, 0x78, 0x19, 0x56, 0x12, 0xc5, 0x48, 0xa4, 0x8e,
0x9c, 0x66, 0x7a, 0x38, 0x92, 0x23, 0xc2, 0x3f, 0x3a, 0x86, 0x59, 0x47, 0xda, 0x2c, 0xe8, 0x30,
0x72, 0x06, 0xad, 0x40, 0x8e, 0x0a, 0x79, 0x30, 0x43, 0x50, 0x44, 0xd9, 0x30, 0xe1, 0x6c, 0x66,
0x6c, 0xe9, 0xff, 0x0f, 0x33, 0x22, 0x8e, 0x84, 0x04, 0xb3, 0xe6, 0xdc, 0x70, 0x50, 0x9f, 0x11,
0x10, 0x04, 0x05, 0x6b, 0xc6, 0x0f, 0x34, 0x58, 0x62, 0x7d, 0x44, 0x40, 0x43, 0x34, 0x02, 0xf7,
0x32, 0x1a, 0x81, 0x5c, 0xae, 0x0c, 0xff, 0x4c, 0xd4, 0x01, 0x7c, 0x58, 0x50, 0x05, 0x11, 0x5a,
0xbc, 0x03, 0x65, 0xd6, 0x4a, 0xda, 0x16, 0xb5, 0xa4, 0x08, 0xcf, 0x8e, 0xcb, 0x4f, 0xa4, 0xc1,
0xa0, 0x59, 0x2b, 0xf5, 0xda, 0xee, 0xb7, 0x71, 0x9b, 0xbe, 0x8a, 0xa9, 0x15, 0x05, 0x52, 0x34,
0x87, 0x42, 0xaa, 0xcc, 0xeb, 0xae, 0x67, 0x63, 0x5e, 0x33, 0x0b, 0xaa, 0xd7, 0x6f, 0xca, 0x79,
0x14, 0x42, 0x24, 0x6a, 0x6c, 0x71, 0xa2, 0x1a, 0x7b, 0x1f, 0x96, 0xdc, 0xa4, 0x85, 0xab, 0x25,
0xae, 0x4c, 0xf3, 0x10, 0x7b, 0x26, 0xd1, 0xcc, 0xb3, 0x92, 0xd7, 0xa8, 0xcf, 0xd0, 0x28, 0x13,
0xe3, 0xcf, 0x1a, 0xac, 0x8c, 0xd8, 0xf4, 0x15, 0x87, 0x50, 0xfd, 0xeb, 0x23, 0x76, 0x6d, 0x4c,
0x66, 0x57, 0x86, 0xcd, 0xad, 0x1a, 0x5a, 0x29, 0x98, 0x89, 0xd9, 0xf4, 0x0d, 0x38, 0xee, 0x50,
0xdc, 0x0d, 0x12, 0x40, 0x0e, 0x2d, 0x45, 0x5e, 0x9c, 0x97, 0xb4, 0x8f, 0x6f, 0x31, 0x2a, 0x48,
0x10, 0x33, 0xfe, 0x50, 0x80, 0xe5, 0x6d, 0xcf, 0x6e, 0xb5, 0xf7, 0xb1, 0xdd, 0xef, 0x38, 0xee,
0xde, 0x35, 0xcf, 0xa5, 0xf8, 0x3e, 0x3d, 0x82, 0x20, 0x79, 0x0b, 0x4a, 0xa4, 0x87, 0xdb, 0xb2,
0x8e, 0x5f, 0x1e, 0xaf, 0x4f, 0x9a, 0x8c, 0xad, 0x1e, 0x6e, 0x47, 0x09, 0x93, 0x8d, 0x10, 0xa7,
0xa8, 0xbf, 0xc3, 0x2a, 0x8f, 0x45, 0xfb, 0x84, 0x07, 0xd3, 0xdc, 0xc6, 0x95, 0x29, 0x68, 0x73,
0x7c, 0xb3, 0x22, 0xa9, 0x9f, 0x10, 0x63, 0x24, 0xe9, 0x1a, 0x1f, 0x6a, 0x50, 0x4d, 0x43, 0x3b,
0x82, 0x38, 0x78, 0x53, 0x8d, 0x83, 0x8d, 0xfc, 0xba, 0x65, 0x84, 0xc2, 0x7b, 0x19, 0x3a, 0x31,
0xc3, 0xea, 0x57, 0xe0, 0xa4, 0xc8, 0xd2, 0xd8, 0x66, 0xa1, 0x25, 0x73, 0xf9, 0xb2, 0x24, 0x74,
0xb2, 0x15, 0x5b, 0x43, 0x0a, 0xa4, 0xfe, 0x22, 0x54, 0x7a, 0x1e, 0xc5, 0x2e, 0x75, 0xac, 0x4e,
0x70, 0x58, 0x63, 0xa9, 0x93, 0xe7, 0xaf, 0x6d, 0x65, 0x05, 0x25, 0x20, 0x8d, 0x5f, 0x6a, 0x70,
0x2e, 0xdb, 0x3b, 0xfa, 0x77, 0xa0, 0x12, 0x68, 0x7c, 0xad, 0x63, 0x39, 0xdd, 0xa0, 0x2e, 0x7c,
0x71, 0xb2, 0xce, 0x97, 0xe3, 0x44, 0xb4, 0xa5, 0xcb, 0x4f, 0x4b, 0x9d, 0x2a, 0x0a, 0x18, 0x41,
0x09, 0x56, 0xc6, 0xaf, 0x0a, 0x30, 0xaf, 0x80, 0x1c, 0xc1, 0x96, 0x79, 0x5d, 0xd9, 0x32, 0xcd,
0x3c, 0x6a, 0x66, 0xed, 0x95, 0xdb, 0x89, 0xbd, 0x72, 0x31, 0x0f, 0xd1, 0xf1, 0x9b, 0x64, 0xa8,
0x41, 0x4d, 0x81, 0xbf, 0xe6, 0xb9, 0xa4, 0xdf, 0x65, 0xa7, 0xab, 0x3b, 0xd8, 0xc7, 0xac, 0xf9,
0x39, 0x0f, 0x65, 0xab, 0xe7, 0xdc, 0xf0, 0xbd, 0x7e, 0x2f, 0xd9, 0x1e, 0x5c, 0xdd, 0xde, 0xe2,
0xf3, 0x28, 0x84, 0x60, 0xd0, 0x81, 0x44, 0xb2, 0x4c, 0xc4, 0x0e, 0x2d, 0xf2, 0x34, 0x13, 0x42,
0x84, 0x8d, 0x55, 0x29, 0xb3, 0xb1, 0x32, 0xa1, 0xd8, 0x77, 0x6c, 0xd9, 0x9e, 0x3e, 0x2b, 0x01,
0x8a, 0xb7, 0xb6, 0x36, 0x3f, 0x1e, 0xd4, 0x9f, 0xc9, 0xba, 0x23, 0xa1, 0x0f, 0x7a, 0x98, 0x34,
0x6e, 0x6d, 0x6d, 0x22, 0x86, 0x6c, 0xbc, 0xaf, 0xc1, 0x92, 0xa2, 0xe4, 0x11, 0xa4, 0x80, 0x6d,
0x35, 0x05, 0x7c, 0x21, 0x87, 0xcb, 0x32, 0xf6, 0xfe, 0x4f, 0x8b, 0x70, 0x46, 0x81, 0x8b, 0x9d,
0x2c, 0x3f, 0xf9, 0xb0, 0x7e, 0x17, 0xe6, 0xc3, 0xab, 0xa6, 0xeb, 0xbe, 0xd7, 0x95, 0xf1, 0xfd,
0xe5, 0x1c, 0x7a, 0xc5, 0xce, 0xc6, 0x41, 0x70, 0x89, 0xd3, 0xc9, 0x8d, 0x38, 0x61, 0xa4, 0xf2,
0xc9, 0x7d, 0xcd, 0xa3, 0x77, 0xa0, 0x62, 0x2b, 0x17, 0x04, 0xd5, 0xd2, 0x24, 0x77, 0x5d, 0xea,
0xa5, 0x42, 0x94, 0x62, 0xd4, 0x79, 0x94, 0xa0, 0x6d, 0xfc, 0x4d, 0x83, 0xa7, 0x32, 0xb4, 0x3c,
0x82, 0x28, 0x7b, 0x5b, 0x8d, 0xb2, 0xe7, 0xa7, 0xf2, 0x46, 0x46, 0xbc, 0xfd, 0x4c, 0x83, 0xb5,
0xc3, 0xfc, 0x97, 0x33, 0x39, 0xac, 0x41, 0xe9, 0xae, 0xe3, 0xda, 0xb2, 0xdf, 0x0c, 0xb7, 0xfb,
0x57, 0x1d, 0xd7, 0x46, 0x7c, 0x25, 0x4c, 0x08, 0xc5, 0xcc, 0x3b, 0x8a, 0x87, 0x1a, 0x3c, 0x3d,
0xb6, 0x3a, 0x4c, 0x70, 0x5a, 0xfb, 0x12, 0x2c, 0xf4, 0x5d, 0xd2, 0x77, 0x28, 0x0b, 0x98, 0x78,
0xc1, 0x3b, 0x35, 0x1c, 0xd4, 0x17, 0x6e, 0xa9, 0x4b, 0x28, 0x09, 0x6b, 0xfc, 0xa6, 0x90, 0xc8,
0x27, 0xbc, 0xfc, 0xde, 0x80, 0xa5, 0x58, 0xf9, 0x21, 0x24, 0x76, 0x1b, 0x15, 0x76, 0xaf, 0x28,
0x09, 0x80, 0x46, 0x71, 0xd8, 0x56, 0xeb, 0xc5, 0x4d, 0xfd, 0xbf, 0xdc, 0x6a, 0xca, 0x02, 0x52,
0xf9, 0xe8, 0xdb, 0x50, 0x89, 0x2e, 0xdd, 0x58, 0x27, 0x2d, 0xdd, 0xb0, 0x1e, 0xec, 0x85, 0xab,
0xca, 0xea, 0xc7, 0x23, 0x33, 0x28, 0x81, 0x6f, 0xfc, 0xbb, 0x00, 0xa7, 0x52, 0xca, 0xd1, 0x54,
0x57, 0x76, 0xdf, 0x04, 0x88, 0xa8, 0x4b, 0x9b, 0x34, 0xf2, 0x5d, 0x3c, 0x9a, 0x15, 0x7e, 0xae,
0x8e, 0x66, 0x63, 0x14, 0x75, 0x02, 0x73, 0x3e, 0x26, 0xd8, 0x3f, 0xc0, 0xf6, 0x75, 0xcf, 0x97,
0x17, 0x74, 0x2f, 0xe5, 0x30, 0xfa, 0x48, 0xe9, 0x34, 0x4f, 0x49, 0x95, 0xe6, 0x50, 0x44, 0x18,
0xc5, 0xb9, 0xe8, 0x2d, 0x58, 0xb1, 0x71, 0xfc, 0xa6, 0x93, 0xa7, 0x15, 0x6c, 0xf3, 0x8a, 0x58,
0x8e, 0xee, 0x48, 0x37, 0xd3, 0x80, 0x50, 0x3a, 0xae, 0xf1, 0x57, 0x0d, 0x56, 0x14, 0xc9, 0xde,
0xc0, 0xdd, 0x5e, 0xc7, 0xa2, 0x47, 0x71, 0xac, 0xbc, 0xad, 0xb4, 0x3f, 0x2f, 0xe4, 0x30, 0x5f,
0x20, 0x64, 0x56, 0x1b, 0x64, 0xfc, 0x45, 0x83, 0xb3, 0xa9, 0x18, 0x47, 0x90, 0x68, 0xdf, 0x52,
0x13, 0xed, 0xa5, 0x29, 0xf4, 0xca, 0x48, 0xb3, 0x8f, 0xb3, 0xb4, 0x6a, 0x89, 0x63, 0xd2, 0x67,
0xaf, 0x5f, 0x35, 0x3e, 0x28, 0x2a, 0x6d, 0x37, 0x39, 0x8a, 0xfe, 0x44, 0xcd, 0x28, 0x85, 0x89,
0x32, 0xca, 0x48, 0xa2, 0x2d, 0xe6, 0x4c, 0xb4, 0x84, 0x4c, 0x97, 0x68, 0x6f, 0xc3, 0xbc, 0x5a,
0x7d, 0x4a, 0x13, 0xbe, 0x8d, 0x71, 0xd2, 0x2d, 0xa5, 0x3a, 0xa9, 0x94, 0xf4, 0x57, 0x60, 0x99,
0x50, 0xbf, 0xdf, 0xa6, 0x7d, 0x1f, 0xdb, 0xb1, 0xc7, 0x8d, 0xe3, 0x3c, 0x9f, 0x54, 0x87, 0x83,
0xfa, 0x72, 0x2b, 0x65, 0x1d, 0xa5, 0x62, 0x25, 0x3b, 0x67, 0x42, 0x3e, 0xcd, 0x9d, 0x33, 0xc9,
0xea, 0x64, 0xde, 0x57, 0x3b, 0xe7, 0xb8, 0xd7, 0x3e, 0x0b, 0x9d, 0xf3, 0x98, 0x28, 0x1b, 0xdb,
0x39, 0xd3, 0x94, 0x37, 0x2e, 0x51, 0xd5, 0x0e, 0x29, 0x9b, 0xc9, 0xa7, 0xac, 0x5c, 0x8f, 0x5c,
0x6f, 0xc2, 0xcc, 0x1d, 0x7e, 0xfd, 0x3e, 0x61, 0xdf, 0x1d, 0x28, 0x2a, 0xee, 0xec, 0xcd, 0x05,
0xc9, 0x6a, 0x46, 0x8c, 0x09, 0x0a, 0xa8, 0x25, 0x3b, 0xed, 0xb8, 0x55, 0x3e, 0xcd, 0x9d, 0x76,
0x5c, 0xce, 0x8c, 0xf8, 0xfc, 0xa3, 0xda, 0x69, 0xa7, 0xfa, 0xfb, 0xe8, 0x3b, 0x6d, 0x76, 0xf2,
0x62, 0xbf, 0xa4, 0x67, 0xb5, 0x83, 0x13, 0x7a, 0x78, 0xf2, 0xba, 0x19, 0x2c, 0xa0, 0x08, 0xc6,
0xf8, 0x40, 0x83, 0x8a, 0xea, 0xce, 0xa9, 0x1a, 0xbd, 0x87, 0x1a, 0x9c, 0xf2, 0x15, 0x32, 0xf1,
0xb7, 0xe6, 0x8b, 0x79, 0xc2, 0x49, 0x5c, 0x1e, 0x3f, 0x25, 0x19, 0x9e, 0x4a, 0x59, 0x44, 0x69,
0xac, 0x8c, 0xef, 0x6b, 0x90, 0x06, 0xac, 0xbb, 0x19, 0xef, 0x03, 0x1b, 0x79, 0xde, 0x07, 0x64,
0xa4, 0x4f, 0xf2, 0x38, 0xf0, 0xf7, 0x98, 0x45, 0xc5, 0xb7, 0x15, 0x53, 0x59, 0x74, 0x0d, 0x4a,
0x7c, 0x5b, 0x24, 0xa2, 0x61, 0xd3, 0xa2, 0x16, 0xe2, 0x2b, 0xba, 0x0f, 0x95, 0xa8, 0x00, 0xb0,
0x79, 0x5e, 0x30, 0x0e, 0xbd, 0xf2, 0x8d, 0x4a, 0x49, 0xe2, 0x53, 0x11, 0xae, 0x5c, 0x4b, 0xa1,
0x88, 0x12, 0x1c, 0x8c, 0x1f, 0x17, 0x60, 0x21, 0xf1, 0xc2, 0x9d, 0xfa, 0x2e, 0xaf, 0x7d, 0xd2,
0xef, 0xf2, 0xdf, 0xd3, 0x60, 0xd9, 0x57, 0x05, 0x89, 0x47, 0xdc, 0x46, 0xae, 0x47, 0x7a, 0x11,
0x72, 0xab, 0x92, 0xfd, 0x72, 0xda, 0x2a, 0x4a, 0xe5, 0x66, 0xfc, 0x50, 0x83, 0x54, 0x70, 0xdd,
0xcb, 0x88, 0xba, 0x4b, 0xf9, 0x5e, 0xa5, 0xc4, 0x37, 0x04, 0x93, 0x84, 0xdd, 0xef, 0x8b, 0x50,
0xcd, 0x72, 0xad, 0xfe, 0x5d, 0x0d, 0x56, 0x84, 0x09, 0x13, 0xb9, 0x6a, 0x3a, 0x47, 0x85, 0x47,
0x9c, 0x9d, 0x34, 0x9a, 0x28, 0x9d, 0x95, 0x2a, 0x44, 0xfc, 0xbc, 0x3b, 0xdd, 0x57, 0x1c, 0xa3,
0x42, 0x28, 0x67, 0xe8, 0x74, 0x56, 0xca, 0x13, 0x5a, 0xe9, 0xd0, 0x27, 0xb4, 0x6f, 0xc1, 0x8c,
0xcf, 0x4f, 0xa1, 0xac, 0x19, 0x9b, 0xe0, 0x69, 0x34, 0xfd, 0xb3, 0xa0, 0xa8, 0x40, 0x8a, 0x31,
0x41, 0x01, 0x55, 0xe3, 0xb7, 0x1a, 0x8c, 0x44, 0xfb, 0x54, 0xe9, 0xc2, 0x02, 0xe8, 0xfd, 0x97,
0x06, 0x0d, 0x59, 0xc4, 0xac, 0x18, 0x23, 0x6a, 0x9a, 0x8f, 0x9e, 0xd4, 0x8e, 0x3d, 0x7e, 0x52,
0x3b, 0xf6, 0xd1, 0x93, 0xda, 0xb1, 0x87, 0xc3, 0x9a, 0xf6, 0x68, 0x58, 0xd3, 0x1e, 0x0f, 0x6b,
0xda, 0x47, 0xc3, 0x9a, 0xf6, 0x8f, 0x61, 0x4d, 0x7b, 0xef, 0x9f, 0xb5, 0x63, 0x6f, 0xaf, 0x8e,
0xfb, 0x80, 0xf0, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x20, 0x09, 0x51, 0x5f, 0x28, 0x00,
0x00,
}
func (m *AllocationResult) Marshal() (dAtA []byte, err error) {
@ -1747,6 +1749,13 @@ func (m *NamedResourcesAttributeValue) MarshalToSizedBuffer(dAtA []byte) (int, e
_ = i
var l int
_ = l
if m.VersionValue != nil {
i -= len(*m.VersionValue)
copy(dAtA[i:], *m.VersionValue)
i = encodeVarintGenerated(dAtA, i, uint64(len(*m.VersionValue)))
i--
dAtA[i] = 0x52
}
if m.StringSliceValue != nil {
{
size, err := m.StringSliceValue.MarshalToSizedBuffer(dAtA[:i])
@ -3592,6 +3601,10 @@ func (m *NamedResourcesAttributeValue) Size() (n int) {
l = m.StringSliceValue.Size()
n += 1 + l + sovGenerated(uint64(l))
}
if m.VersionValue != nil {
l = len(*m.VersionValue)
n += 1 + l + sovGenerated(uint64(l))
}
return n
}
@ -4289,6 +4302,7 @@ func (this *NamedResourcesAttributeValue) String() string {
`IntValue:` + valueToStringGenerated(this.IntValue) + `,`,
`IntSliceValue:` + strings.Replace(this.IntSliceValue.String(), "NamedResourcesIntSlice", "NamedResourcesIntSlice", 1) + `,`,
`StringSliceValue:` + strings.Replace(this.StringSliceValue.String(), "NamedResourcesStringSlice", "NamedResourcesStringSlice", 1) + `,`,
`VersionValue:` + valueToStringGenerated(this.VersionValue) + `,`,
`}`,
}, "")
return s
@ -5695,6 +5709,39 @@ func (m *NamedResourcesAttributeValue) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VersionValue", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.VersionValue = &s
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])

View File

@ -134,6 +134,9 @@ message NamedResourcesAttributeValue {
// StringSliceValue is an array of strings.
optional NamedResourcesStringSlice stringSlice = 9;
// VersionValue is a semantic version according to semver.org spec 2.0.0.
optional string version = 10;
}
// NamedResourcesFilter is used in ResourceFilterModel.

View File

@ -70,7 +70,8 @@ type NamedResourcesAttributeValue struct {
StringValue *string `json:"string,omitempty" protobuf:"bytes,5,opt,name=string"`
// StringSliceValue is an array of strings.
StringSliceValue *NamedResourcesStringSlice `json:"stringSlice,omitempty" protobuf:"bytes,9,rep,name=stringSlice"`
// TODO: VersionValue *SemVersion `json:"version,omitempty" protobuf:"bytes,7,opt,name=version"`
// VersionValue is a semantic version according to semver.org spec 2.0.0.
VersionValue *string `json:"version,omitempty" protobuf:"bytes,10,opt,name=version"`
}
// NamedResourcesIntSlice contains a slice of 64-bit integers.
@ -89,17 +90,6 @@ type NamedResourcesStringSlice struct {
Strings []string `json:"strings" protobuf:"bytes,1,opt,name=strings"`
}
// TODO
//
// A wrapper around https://pkg.go.dev/github.com/blang/semver/v4#Version which
// is encoded as a string. During decoding, it validates that the string
// can be parsed using tolerant parsing (currently trims spaces, removes a "v" prefix,
// adds a 0 patch number to versions with only major and minor components specified,
// and removes leading 0s).
// type NamedResourcesSemVersion struct {
// semver.Version
//}
// NamedResourcesRequest is used in ResourceRequestModel.
type NamedResourcesRequest struct {
// Selector is a CEL expression which must evaluate to true if a

View File

@ -183,6 +183,11 @@ func (in *NamedResourcesAttributeValue) DeepCopyInto(out *NamedResourcesAttribut
*out = new(NamedResourcesStringSlice)
(*in).DeepCopyInto(*out)
}
if in.VersionValue != nil {
in, out := &in.VersionValue, &out.VersionValue
*out = new(string)
**out = **in
}
return
}

View File

@ -65,7 +65,8 @@
"strings": [
"stringsValue"
]
}
},
"version": "versionValue"
}
]
}

View File

@ -47,5 +47,6 @@ namedResources:
stringSlice:
strings:
- stringsValue
version: versionValue
name: nameValue
nodeName: nodeNameValue

View File

@ -12001,6 +12001,9 @@ var schemaYAML = typed.YAMLObject(`types:
- name: stringSlice
type:
namedType: io.k8s.api.resource.v1alpha2.NamedResourcesStringSlice
- name: version
type:
scalar: string
- name: io.k8s.api.resource.v1alpha2.NamedResourcesFilter
map:
fields:

View File

@ -90,3 +90,11 @@ func (b *NamedResourcesAttributeApplyConfiguration) WithStringSliceValue(value *
b.StringSliceValue = value
return b
}
// WithVersionValue sets the VersionValue field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the VersionValue field is set to the value of the last call.
func (b *NamedResourcesAttributeApplyConfiguration) WithVersionValue(value string) *NamedResourcesAttributeApplyConfiguration {
b.VersionValue = &value
return b
}

View File

@ -31,6 +31,7 @@ type NamedResourcesAttributeValueApplyConfiguration struct {
IntSliceValue *NamedResourcesIntSliceApplyConfiguration `json:"intSlice,omitempty"`
StringValue *string `json:"string,omitempty"`
StringSliceValue *NamedResourcesStringSliceApplyConfiguration `json:"stringSlice,omitempty"`
VersionValue *string `json:"version,omitempty"`
}
// NamedResourcesAttributeValueApplyConfiguration constructs an declarative configuration of the NamedResourcesAttributeValue type for use with
@ -86,3 +87,11 @@ func (b *NamedResourcesAttributeValueApplyConfiguration) WithStringSliceValue(va
b.StringSliceValue = value
return b
}
// WithVersionValue sets the VersionValue field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the VersionValue field is set to the value of the last call.
func (b *NamedResourcesAttributeValueApplyConfiguration) WithVersionValue(value string) *NamedResourcesAttributeValueApplyConfiguration {
b.VersionValue = &value
return b
}

View File

@ -5,6 +5,7 @@ module k8s.io/dynamic-resource-allocation
go 1.22.0
require (
github.com/blang/semver/v4 v4.0.0
github.com/go-logr/logr v1.4.1
github.com/google/cel-go v0.17.8
github.com/google/go-cmp v0.6.0

View File

@ -6,6 +6,7 @@ github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/g
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=

View File

@ -21,6 +21,7 @@ import (
"fmt"
"reflect"
"github.com/blang/semver/v4"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/traits"
@ -105,43 +106,54 @@ var valueTypes = map[string]struct {
celType *cel.Type
// get returns nil if the attribute doesn't have the type, otherwise
// the value of that type.
get func(attr resourceapi.NamedResourcesAttribute) any
get func(attr resourceapi.NamedResourcesAttribute) (any, error)
}{
"quantity": {apiservercel.QuantityType, func(attr resourceapi.NamedResourcesAttribute) any {
"quantity": {apiservercel.QuantityType, func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.QuantityValue == nil {
return nil
return nil, nil
}
return apiservercel.Quantity{Quantity: attr.QuantityValue}
return apiservercel.Quantity{Quantity: attr.QuantityValue}, nil
}},
"bool": {cel.BoolType, func(attr resourceapi.NamedResourcesAttribute) any {
"bool": {cel.BoolType, func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.BoolValue == nil {
return nil
return nil, nil
}
return *attr.BoolValue
return *attr.BoolValue, nil
}},
"int": {cel.IntType, func(attr resourceapi.NamedResourcesAttribute) any {
"int": {cel.IntType, func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.IntValue == nil {
return nil
return nil, nil
}
return *attr.IntValue
return *attr.IntValue, nil
}},
"intslice": {types.NewListType(cel.IntType), func(attr resourceapi.NamedResourcesAttribute) any {
"intslice": {types.NewListType(cel.IntType), func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.IntSliceValue == nil {
return nil
return nil, nil
}
return attr.IntSliceValue.Ints
return attr.IntSliceValue.Ints, nil
}},
"string": {cel.StringType, func(attr resourceapi.NamedResourcesAttribute) any {
"string": {cel.StringType, func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.StringValue == nil {
return nil
return nil, nil
}
return *attr.StringValue
return *attr.StringValue, nil
}},
"stringslice": {types.NewListType(cel.StringType), func(attr resourceapi.NamedResourcesAttribute) any {
"stringslice": {types.NewListType(cel.StringType), func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.StringSliceValue == nil {
return nil
return nil, nil
}
return attr.StringSliceValue.Strings
return attr.StringSliceValue.Strings, nil
}},
"version": {SemverType, func(attr resourceapi.NamedResourcesAttribute) (any, error) {
if attr.VersionValue == nil {
return nil, nil
}
v, err := semver.Parse(*attr.VersionValue)
if err != nil {
return nil, fmt.Errorf("parse semantic version: %v", err)
}
return Semver{Version: v}, nil
}},
}
@ -150,7 +162,11 @@ var boolType = reflect.TypeOf(true)
func (c CompilationResult) Evaluate(ctx context.Context, attributes []resourceapi.NamedResourcesAttribute) (bool, error) {
variables := make(map[string]any, len(valueTypes))
for name, valueType := range valueTypes {
variables[attributesVarPrefix+name] = buildValueMapper(c.Environment.CELTypeAdapter(), attributes, valueType.get)
m, err := buildValueMapper(c.Environment.CELTypeAdapter(), attributes, valueType.get)
if err != nil {
return false, fmt.Errorf("extract attributes with type %s: %v", name, err)
}
variables[attributesVarPrefix+name] = m
}
result, _, err := c.Program.ContextEval(ctx, variables)
if err != nil {
@ -172,7 +188,9 @@ func mustBuildEnv() *environment.EnvSet {
versioned := []environment.VersionedOptions{
{
IntroducedVersion: version.MajorMinor(1, 30),
EnvOptions: buildVersionedAttributes(),
EnvOptions: append(buildVersionedAttributes(),
SemverLib(),
),
},
}
envset, err := envset.Extend(versioned...)
@ -190,17 +208,21 @@ func buildVersionedAttributes() []cel.EnvOption {
return options
}
func buildValueMapper(adapter types.Adapter, attributes []resourceapi.NamedResourcesAttribute, get func(resourceapi.NamedResourcesAttribute) any) traits.Mapper {
func buildValueMapper(adapter types.Adapter, attributes []resourceapi.NamedResourcesAttribute, get func(resourceapi.NamedResourcesAttribute) (any, error)) (traits.Mapper, error) {
// This implementation constructs a map and then let's cel handle the
// lookup and iteration. This is done for the sake of simplicity.
// Whether it's faster than writing a custom mapper depends on
// real-world attribute sets and CEL expressions and would have to be
// benchmarked.
valueMap := make(map[string]any)
for _, attribute := range attributes {
if value := get(attribute); value != nil {
for name, attribute := range attributes {
value, err := get(attribute)
if err != nil {
return nil, fmt.Errorf("attribute %q: %v", name, err)
}
if value != nil {
valueMap[attribute.Name] = value
}
}
return types.NewStringInterfaceMap(adapter, valueMap)
return types.NewStringInterfaceMap(adapter, valueMap), nil
}

View File

@ -0,0 +1,73 @@
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cel
import (
"fmt"
"reflect"
"github.com/blang/semver/v4"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)
var (
SemverType = cel.ObjectType("kubernetes.Semver")
)
// Semver provdes a CEL representation of a [semver.Version].
type Semver struct {
semver.Version
}
func (v Semver) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
if reflect.TypeOf(v.Version).AssignableTo(typeDesc) {
return v.Version, nil
}
if reflect.TypeOf("").AssignableTo(typeDesc) {
return v.Version.String(), nil
}
return nil, fmt.Errorf("type conversion error from 'Semver' to '%v'", typeDesc)
}
func (v Semver) ConvertToType(typeVal ref.Type) ref.Val {
switch typeVal {
case SemverType:
return v
case types.TypeType:
return SemverType
default:
return types.NewErr("type conversion error from '%s' to '%s'", SemverType, typeVal)
}
}
func (v Semver) Equal(other ref.Val) ref.Val {
otherDur, ok := other.(Semver)
if !ok {
return types.MaybeNoSuchOverloadErr(other)
}
return types.Bool(v.Version.EQ(otherDur.Version))
}
func (v Semver) Type() ref.Type {
return SemverType
}
func (v Semver) Value() interface{} {
return v.Version
}

View File

@ -0,0 +1,209 @@
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cel_test
import (
"regexp"
"testing"
"github.com/blang/semver/v4"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/util/sets"
library "k8s.io/dynamic-resource-allocation/structured/namedresources/cel"
)
func testSemver(t *testing.T, expr string, expectResult ref.Val, expectRuntimeErrPattern string, expectCompileErrs []string) {
env, err := cel.NewEnv(
library.SemverLib(),
)
if err != nil {
t.Fatalf("%v", err)
}
compiled, issues := env.Compile(expr)
if len(expectCompileErrs) > 0 {
missingCompileErrs := []string{}
matchedCompileErrs := sets.New[int]()
for _, expectedCompileErr := range expectCompileErrs {
compiledPattern, err := regexp.Compile(expectedCompileErr)
if err != nil {
t.Fatalf("failed to compile expected err regex: %v", err)
}
didMatch := false
for i, compileError := range issues.Errors() {
if compiledPattern.Match([]byte(compileError.Message)) {
didMatch = true
matchedCompileErrs.Insert(i)
}
}
if !didMatch {
missingCompileErrs = append(missingCompileErrs, expectedCompileErr)
} else if len(matchedCompileErrs) != len(issues.Errors()) {
unmatchedErrs := []cel.Error{}
for i, issue := range issues.Errors() {
if !matchedCompileErrs.Has(i) {
unmatchedErrs = append(unmatchedErrs, *issue)
}
}
require.Empty(t, unmatchedErrs, "unexpected compilation errors")
}
}
require.Empty(t, missingCompileErrs, "expected compilation errors")
return
} else if len(issues.Errors()) > 0 {
for _, err := range issues.Errors() {
t.Errorf("unexpected compile error: %v", err)
}
t.FailNow()
}
prog, err := env.Program(compiled)
if err != nil {
t.Fatalf("%v", err)
}
res, _, err := prog.Eval(map[string]interface{}{})
if len(expectRuntimeErrPattern) > 0 {
if err == nil {
t.Fatalf("no runtime error thrown. Expected: %v", expectRuntimeErrPattern)
} else if matched, regexErr := regexp.MatchString(expectRuntimeErrPattern, err.Error()); regexErr != nil {
t.Fatalf("failed to compile expected err regex: %v", regexErr)
} else if !matched {
t.Fatalf("unexpected err: %v", err)
}
} else if err != nil {
t.Fatalf("%v", err)
} else if expectResult != nil {
converted := res.Equal(expectResult).Value().(bool)
require.True(t, converted, "expectation not equal to output")
} else {
t.Fatal("expected result must not be nil")
}
}
func TestSemver(t *testing.T) {
trueVal := types.Bool(true)
falseVal := types.Bool(false)
cases := []struct {
name string
expr string
expectValue ref.Val
expectedCompileErr []string
expectedRuntimeErr string
}{
{
name: "parse",
expr: `semver("1.2.3")`,
expectValue: library.Semver{Version: semver.MustParse("1.2.3")},
},
{
name: "parseInvalidVersion",
expr: `semver("v1.0")`,
expectedRuntimeErr: "No Major.Minor.Patch elements found",
},
{
name: "isSemver",
expr: `isSemver("1.2.3-beta.1+build.1")`,
expectValue: trueVal,
},
{
name: "isSemver_false",
expr: `isSemver("v1.0")`,
expectValue: falseVal,
},
{
name: "isSemver_noOverload",
expr: `isSemver([1, 2, 3])`,
expectedCompileErr: []string{"found no matching overload for 'isSemver' applied to.*"},
},
{
name: "equality_reflexivity",
expr: `semver("1.2.3") == semver("1.2.3")`,
expectValue: trueVal,
},
{
name: "inequality",
expr: `semver("1.2.3") == semver("1.0.0")`,
expectValue: falseVal,
},
{
name: "semver_less",
expr: `semver("1.0.0").isLessThan(semver("1.2.3"))`,
expectValue: trueVal,
},
{
name: "semver_less_false",
expr: `semver("1.0.0").isLessThan(semver("1.0.0"))`,
expectValue: falseVal,
},
{
name: "semver_greater",
expr: `semver("1.2.3").isGreaterThan(semver("1.0.0"))`,
expectValue: trueVal,
},
{
name: "semver_greater_false",
expr: `semver("1.0.0").isGreaterThan(semver("1.0.0"))`,
expectValue: falseVal,
},
{
name: "compare_equal",
expr: `semver("1.2.3").compareTo(semver("1.2.3"))`,
expectValue: types.Int(0),
},
{
name: "compare_less",
expr: `semver("1.0.0").compareTo(semver("1.2.3"))`,
expectValue: types.Int(-1),
},
{
name: "compare_greater",
expr: `semver("1.2.3").compareTo(semver("1.0.0"))`,
expectValue: types.Int(1),
},
{
name: "major",
expr: `semver("1.2.3").major()`,
expectValue: types.Int(1),
},
{
name: "minor",
expr: `semver("1.2.3").minor()`,
expectValue: types.Int(2),
},
{
name: "patch",
expr: `semver("1.2.3").patch()`,
expectValue: types.Int(3),
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
testSemver(t, c.expr, c.expectValue, c.expectedRuntimeErr, c.expectedCompileErr)
})
}
}

View File

@ -0,0 +1,238 @@
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cel
import (
"github.com/blang/semver/v4"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)
// Semver provides a CEL function library extension for [semver.Version].
//
// semver
//
// Converts a string to a semantic version or results in an error if the string is not a valid semantic version. Refer
// to semver.org documentation for information on accepted patterns.
//
// semver(<string>) <Semver>
//
// Examples:
//
// semver('1.0.0') // returns a Semver
// semver('0.1.0-alpha.1') // returns a Semver
// semver('200K') // error
// semver('Three') // error
// semver('Mi') // error
//
// isSemver
//
// Returns true if a string is a valid Semver. isSemver returns true if and
// only if semver does not result in error.
//
// isSemver( <string>) <bool>
//
// Examples:
//
// isSemver('1.0.0') // returns true
// isSemver('v1.0') // returns true (tolerant parsing)
// isSemver('hello') // returns false
//
// Conversion to Scalars:
//
// - major/minor/patch: return the major version number as int64.
//
// <Semver>.major() <int>
//
// Examples:
//
// semver("1.2.3").major() // returns 1
//
// Comparisons
//
// - isGreaterThan: Returns true if and only if the receiver is greater than the operand
//
// - isLessThan: Returns true if and only if the receiver is less than the operand
//
// - compareTo: Compares receiver to operand and returns 0 if they are equal, 1 if the receiver is greater, or -1 if the receiver is less than the operand
//
//
// <Semver>.isLessThan(<semver>) <bool>
// <Semver>.isGreaterThan(<semver>) <bool>
// <Semver>.compareTo(<semver>) <int>
//
// Examples:
//
// semver("1.2.3").compareTo(semver("1.2.3")) // returns 0
// semver("1.2.3").compareTo(semver("2.0.0")) // returns -1
// semver("1.2.3").compareTo(semver("0.1.2")) // returns 1
func SemverLib() cel.EnvOption {
return cel.Lib(semverLib)
}
var semverLib = &semverLibType{}
type semverLibType struct{}
func (*semverLibType) LibraryName() string {
return "k8s.semver"
}
func (*semverLibType) CompileOptions() []cel.EnvOption {
// Defined in this function to avoid an initialization order problem.
semverLibraryDecls := map[string][]cel.FunctionOpt{
"semver": {
cel.Overload("string_to_semver", []*cel.Type{cel.StringType}, SemverType, cel.UnaryBinding((stringToSemver))),
},
"isSemver": {
cel.Overload("is_semver_string", []*cel.Type{cel.StringType}, cel.BoolType, cel.UnaryBinding(isSemver)),
},
"isGreaterThan": {
cel.MemberOverload("semver_is_greater_than", []*cel.Type{SemverType, SemverType}, cel.BoolType, cel.BinaryBinding(semverIsGreaterThan)),
},
"isLessThan": {
cel.MemberOverload("semver_is_less_than", []*cel.Type{SemverType, SemverType}, cel.BoolType, cel.BinaryBinding(semverIsLessThan)),
},
"compareTo": {
cel.MemberOverload("semver_compare_to", []*cel.Type{SemverType, SemverType}, cel.IntType, cel.BinaryBinding(semverCompareTo)),
},
"major": {
cel.MemberOverload("semver_major", []*cel.Type{SemverType}, cel.IntType, cel.UnaryBinding(semverMajor)),
},
"minor": {
cel.MemberOverload("semver_minor", []*cel.Type{SemverType}, cel.IntType, cel.UnaryBinding(semverMinor)),
},
"patch": {
cel.MemberOverload("semver_patch", []*cel.Type{SemverType}, cel.IntType, cel.UnaryBinding(semverPatch)),
},
}
options := make([]cel.EnvOption, 0, len(semverLibraryDecls))
for name, overloads := range semverLibraryDecls {
options = append(options, cel.Function(name, overloads...))
}
return options
}
func (*semverLibType) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func isSemver(arg ref.Val) ref.Val {
str, ok := arg.Value().(string)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
// Using semver/v4 here is okay because this function isn't
// used to validate the Kubernetes API. In the CEL base library
// we would have to use the regular expression from
// pkg/apis/resource/structured/namedresources/validation/validation.go.
_, err := semver.Parse(str)
if err != nil {
return types.Bool(false)
}
return types.Bool(true)
}
func stringToSemver(arg ref.Val) ref.Val {
str, ok := arg.Value().(string)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
// Using semver/v4 here is okay because this function isn't
// used to validate the Kubernetes API. In the CEL base library
// we would have to use the regular expression from
// pkg/apis/resource/structured/namedresources/validation/validation.go
// first before parsing.
v, err := semver.Parse(str)
if err != nil {
return types.WrapErr(err)
}
return Semver{Version: v}
}
func semverMajor(arg ref.Val) ref.Val {
v, ok := arg.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Int(v.Major)
}
func semverMinor(arg ref.Val) ref.Val {
v, ok := arg.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Int(v.Minor)
}
func semverPatch(arg ref.Val) ref.Val {
v, ok := arg.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Int(v.Patch)
}
func semverIsGreaterThan(arg ref.Val, other ref.Val) ref.Val {
v, ok := arg.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
v2, ok := other.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Bool(v.Compare(v2) == 1)
}
func semverIsLessThan(arg ref.Val, other ref.Val) ref.Val {
v, ok := arg.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
v2, ok := other.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Bool(v.Compare(v2) == -1)
}
func semverCompareTo(arg ref.Val, other ref.Val) ref.Val {
v, ok := arg.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
v2, ok := other.Value().(semver.Version)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Int(v.Compare(v2))
}