mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-21 00:33:15 +00:00
Merge pull request #133948 from lalitc375/cherry-pick-pr-170
Add support for UUID format.
This commit is contained in:
@@ -24,6 +24,10 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
const (
|
||||
uuidErrorMessage = "must be a lowercase UUID in 8-4-4-4-12 format"
|
||||
)
|
||||
|
||||
// ShortName verifies that the specified value is a valid "short name"
|
||||
// (sometimes known as a "DNS label").
|
||||
// - must not be empty
|
||||
@@ -65,3 +69,32 @@ func LongName[T ~string](_ context.Context, op operation.Operation, fldPath *fie
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// UUID verifies that the specified value is a valid UUID (RFC 4122).
|
||||
// - must be 36 characters long
|
||||
// - must be in the normalized form `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||
// - must use only lowercase hexadecimal characters
|
||||
func UUID[T ~string](_ context.Context, op operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
val := (string)(*value)
|
||||
if len(val) != 36 {
|
||||
return field.ErrorList{field.Invalid(fldPath, val, uuidErrorMessage).WithOrigin("format=k8s-uuid")}
|
||||
}
|
||||
for idx := 0; idx < len(val); idx++ {
|
||||
character := val[idx]
|
||||
switch idx {
|
||||
case 8, 13, 18, 23:
|
||||
if character != '-' {
|
||||
return field.ErrorList{field.Invalid(fldPath, val, uuidErrorMessage).WithOrigin("format=k8s-uuid")}
|
||||
}
|
||||
default:
|
||||
// should be lower case hexadecimal.
|
||||
if (character < '0' || character > '9') && (character < 'a' || character > 'f') {
|
||||
return field.ErrorList{field.Invalid(fldPath, val, uuidErrorMessage).WithOrigin("format=k8s-uuid")}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
217
staging/src/k8s.io/apimachinery/pkg/api/validate/strfmt_test.go
Normal file
217
staging/src/k8s.io/apimachinery/pkg/api/validate/strfmt_test.go
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
Copyright 2025 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 validate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/operation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func TestShortName(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
fldPath := field.NewPath("test")
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
wantErrs field.ErrorList
|
||||
}{{
|
||||
name: "valid",
|
||||
input: "abc-123",
|
||||
wantErrs: nil,
|
||||
}, {
|
||||
name: "invalid: empty",
|
||||
input: "",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "", "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character").WithOrigin("format=k8s-short-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: too long",
|
||||
input: "01234567890123456789012345678901234567890123456789012345678901234",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "01234567890123456789012345678901234567890123456789012345678901234", "must be no more than 63 bytes").WithOrigin("format=k8s-short-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: starts with dash",
|
||||
input: "-abc-123",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "-abc-123", "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character").WithOrigin("format=k8s-short-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: ends with dash",
|
||||
input: "abc-123-",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "abc-123-", "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character").WithOrigin("format=k8s-short-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: upper-case",
|
||||
input: "ABC-123",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "ABC-123", "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character").WithOrigin("format=k8s-short-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: other chars",
|
||||
input: "abc_123",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "abc_123", "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character").WithOrigin("format=k8s-short-name"),
|
||||
},
|
||||
}}
|
||||
|
||||
matcher := field.ErrorMatcher{}.ByType().ByField().ByOrigin().ByDetailSubstring()
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
value := tc.input
|
||||
gotErrs := ShortName(ctx, operation.Operation{}, fldPath, &value, nil)
|
||||
matcher.Test(t, tc.wantErrs, gotErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLongName(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
fldPath := field.NewPath("test")
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
wantErrs field.ErrorList
|
||||
}{{
|
||||
name: "valid",
|
||||
input: "a.b.c",
|
||||
wantErrs: nil,
|
||||
}, {
|
||||
name: "invalid: empty",
|
||||
input: "",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character").WithOrigin("format=k8s-long-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: too long",
|
||||
input: "0123456789012345678901234567890123456789012345678901234567890123.0123456789012345678901234567890123456789012345678901234567890123.0123456789012345678901234567890123456789012345678901234567890123.01234567890123456789012345678901234567890123456789012345678901234",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "0123456789012345678901234567890123456789012345678901234567890123.0123456789012345678901234567890123456789012345678901234567890123.0123456789012345678901234567890123456789012345678901234567890123.01234567890123456789012345678901234567890123456789012345678901234", "must be no more than 253 bytes").WithOrigin("format=k8s-long-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: starts with dash",
|
||||
input: "-a.b.c",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "-a.b.c", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character").WithOrigin("format=k8s-long-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: ends with dash",
|
||||
input: "a.b.c-",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "a.b.c-", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character").WithOrigin("format=k8s-long-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: upper-case",
|
||||
input: "A.b.c",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "A.b.c", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character").WithOrigin("format=k8s-long-name"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: other chars",
|
||||
input: "a_b.c",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "a_b.c", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character").WithOrigin("format=k8s-long-name"),
|
||||
},
|
||||
}}
|
||||
|
||||
matcher := field.ErrorMatcher{}.ByType().ByField().ByOrigin().ByDetailSubstring()
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
value := tc.input
|
||||
gotErrs := LongName(ctx, operation.Operation{}, fldPath, &value, nil)
|
||||
matcher.Test(t, tc.wantErrs, gotErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestK8sUUID(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
fldPath := field.NewPath("test")
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
wantErrs field.ErrorList
|
||||
}{{
|
||||
name: "valid uuid with hyphens",
|
||||
input: "123e4567-e89b-12d3-a456-426614174000",
|
||||
wantErrs: nil,
|
||||
}, {
|
||||
name: "invalid uuid with hyphens uppercase",
|
||||
input: "123E4567-E89B-12D3-A456-426614174000",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "123E4567-E89B-12D3-A456-426614174000", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid uuid with urn prefix",
|
||||
input: "urn:uuid:123e4567-e89b-12d3-a456-426614174000",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "urn:uuid:123e4567-e89b-12d3-a456-426614174000", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid uuid without hyphens",
|
||||
input: "123e4567e89b12d3a456426614174000",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "123e4567e89b12d3a456426614174000", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: wrong length",
|
||||
input: "123e4567-e89b-12d3-a456-42661417400",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "123e4567-e89b-12d3-a456-42661417400", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: wrong characters",
|
||||
input: "123e4567-e89b-12d3-a456-42661417400g",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "123e4567-e89b-12d3-a456-42661417400g", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "invalid: misplaced hyphens",
|
||||
input: "123e4567-e89b-12d3-a4564-26614174000",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "123e4567-e89b-12d3-a4564-26614174000", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "empty string",
|
||||
input: "",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}, {
|
||||
name: "not a uuid",
|
||||
input: "not-a-uuid",
|
||||
wantErrs: field.ErrorList{
|
||||
field.Invalid(fldPath, "not-a-uuid", "must be a lowercase UUID in 8-4-4-4-12 format").WithOrigin("format=k8s-uuid"),
|
||||
},
|
||||
}}
|
||||
|
||||
matcher := field.ErrorMatcher{}.ByType().ByField().ByOrigin().ByDetailExact()
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
value := tc.input
|
||||
gotErrs := UUID(ctx, operation.Operation{}, fldPath, &value, nil)
|
||||
matcher.Test(t, tc.wantErrs, gotErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2025 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.
|
||||
*/
|
||||
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
|
||||
|
||||
// This is a test package.
|
||||
package k8suuid
|
||||
|
||||
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
|
||||
var localSchemeBuilder = testscheme.New()
|
||||
|
||||
// MyType is a struct that contains a field with the uuid format.
|
||||
// +k8s:validation:Required
|
||||
type MyType struct {
|
||||
TypeMeta int
|
||||
// +k8s:Optional
|
||||
// +k8s:format=k8s-uuid
|
||||
UUIDField string `json:"uuidField"`
|
||||
// +k8s:Optional
|
||||
// +k8s:format=k8s-uuid
|
||||
UUIDPtrField *string `json:"uuidPtrField"`
|
||||
// Note: no validation here
|
||||
UUIDTypedefField UUIDStringType `json:"uuidTypedefField"`
|
||||
}
|
||||
|
||||
// +k8s:format=k8s-uuid
|
||||
type UUIDStringType string
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2025 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 k8suuid
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func TestK8sUUID(t *testing.T) {
|
||||
st := localSchemeBuilder.Test(t)
|
||||
|
||||
st.Value(&MyType{
|
||||
UUIDField: "123e4567-e89b-12d3-a456-426614174000",
|
||||
UUIDPtrField: ptr.To("123e4567-e89b-12d3-a456-426614174000"),
|
||||
UUIDTypedefField: "123e4567-e89b-12d3-a456-426614174000",
|
||||
}).ExpectValid()
|
||||
|
||||
invalidStruct := &MyType{
|
||||
UUIDField: "123E4567-E89B-12D3-A456-426614174000",
|
||||
UUIDPtrField: ptr.To("123E4567-E89B-12D3-A456-426614174000"),
|
||||
UUIDTypedefField: "123E4567-E89B-12D3-A456-426614174000",
|
||||
}
|
||||
st.Value(invalidStruct).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByOrigin(), field.ErrorList{
|
||||
field.Invalid(field.NewPath("uuidField"), nil, "").WithOrigin("format=k8s-uuid"),
|
||||
field.Invalid(field.NewPath("uuidPtrField"), nil, "").WithOrigin("format=k8s-uuid"),
|
||||
field.Invalid(field.NewPath("uuidTypedefField"), nil, "").WithOrigin("format=k8s-uuid"),
|
||||
})
|
||||
// Test validation ratcheting
|
||||
st.Value(invalidStruct).OldValue(invalidStruct).ExpectValid()
|
||||
|
||||
invalidStruct = &MyType{
|
||||
UUIDField: "not-a-uuid",
|
||||
UUIDPtrField: ptr.To("not-a-uuid"),
|
||||
UUIDTypedefField: "not-a-uuid",
|
||||
}
|
||||
st.Value(invalidStruct).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByOrigin(), field.ErrorList{
|
||||
field.Invalid(field.NewPath("uuidField"), nil, "").WithOrigin("format=k8s-uuid"),
|
||||
field.Invalid(field.NewPath("uuidPtrField"), nil, "").WithOrigin("format=k8s-uuid"),
|
||||
field.Invalid(field.NewPath("uuidTypedefField"), nil, "").WithOrigin("format=k8s-uuid"),
|
||||
})
|
||||
// Test validation ratcheting
|
||||
st.Value(invalidStruct).OldValue(invalidStruct).ExpectValid()
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package k8suuid
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
||||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *testscheme.Scheme) error {
|
||||
// type MyType
|
||||
scheme.AddValidationFunc((*MyType)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_MyType(ctx, op, nil /* fldPath */, obj.(*MyType), safe.Cast[*MyType](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_MyType validates an instance of MyType according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_MyType(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *MyType) (errs field.ErrorList) {
|
||||
// field MyType.TypeMeta has no validation
|
||||
|
||||
// field MyType.UUIDField
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.UUID(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("uuidField"), &obj.UUIDField, safe.Field(oldObj, func(oldObj *MyType) *string { return &oldObj.UUIDField }))...)
|
||||
|
||||
// field MyType.UUIDPtrField
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.UUID(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("uuidPtrField"), obj.UUIDPtrField, safe.Field(oldObj, func(oldObj *MyType) *string { return oldObj.UUIDPtrField }))...)
|
||||
|
||||
// field MyType.UUIDTypedefField
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *UUIDStringType) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_UUIDStringType(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("uuidTypedefField"), &obj.UUIDTypedefField, safe.Field(oldObj, func(oldObj *MyType) *UUIDStringType { return &oldObj.UUIDTypedefField }))...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_UUIDStringType validates an instance of UUIDStringType according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_UUIDStringType(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *UUIDStringType) (errs field.ErrorList) {
|
||||
errs = append(errs, validate.UUID(ctx, op, fldPath, obj, oldObj)...)
|
||||
|
||||
return errs
|
||||
}
|
||||
@@ -51,6 +51,7 @@ var (
|
||||
// Keep this list alphabetized.
|
||||
longNameValidator = types.Name{Package: libValidationPkg, Name: "LongName"}
|
||||
shortNameValidator = types.Name{Package: libValidationPkg, Name: "ShortName"}
|
||||
uuidValidator = types.Name{Package: libValidationPkg, Name: "UUID"}
|
||||
)
|
||||
|
||||
func (formatTagValidator) GetValidations(context Context, tag codetags.Tag) (Validations, error) {
|
||||
@@ -81,6 +82,8 @@ func getFormatValidationFunction(format string) (FunctionGen, error) {
|
||||
return Function(formatTagName, DefaultFlags, longNameValidator), nil
|
||||
case "k8s-short-name":
|
||||
return Function(formatTagName, DefaultFlags, shortNameValidator), nil
|
||||
case "k8s-uuid":
|
||||
return Function(formatTagName, DefaultFlags, uuidValidator), nil
|
||||
}
|
||||
// TODO: Flesh out the list of validation functions
|
||||
|
||||
@@ -98,6 +101,9 @@ func (ftv formatTagValidator) Docs() TagDoc {
|
||||
}, {
|
||||
Description: "k8s-short-name",
|
||||
Docs: "This field holds a Kubernetes \"short name\", aka a \"DNS label\" value.",
|
||||
}, {
|
||||
Description: "k8s-uuid",
|
||||
Docs: "This field holds a Kubernetes UUID, which conforms to RFC 4122.",
|
||||
}},
|
||||
PayloadsType: codetags.ValueTypeString,
|
||||
PayloadsRequired: true,
|
||||
|
||||
Reference in New Issue
Block a user