mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 03:03:59 +00:00
Merge pull request #121096 from alexzielenski/common-schema
add rest of accessors to common.Schema
This commit is contained in:
commit
088f8c0ec5
@ -54,6 +54,13 @@ func (s *Structural) Format() string {
|
||||
return s.Structural.ValueValidation.Format
|
||||
}
|
||||
|
||||
func (s *Structural) Pattern() string {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return ""
|
||||
}
|
||||
return s.Structural.ValueValidation.Pattern
|
||||
}
|
||||
|
||||
func (s *Structural) Items() common.Schema {
|
||||
return &Structural{Structural: s.Structural.Items}
|
||||
}
|
||||
@ -81,6 +88,48 @@ func (s *Structural) Default() any {
|
||||
return s.Structural.Default.Object
|
||||
}
|
||||
|
||||
func (s *Structural) Minimum() *float64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Structural.ValueValidation.Minimum
|
||||
}
|
||||
|
||||
func (s *Structural) IsExclusiveMinimum() bool {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return false
|
||||
}
|
||||
return s.Structural.ValueValidation.ExclusiveMinimum
|
||||
}
|
||||
|
||||
func (s *Structural) Maximum() *float64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Structural.ValueValidation.Maximum
|
||||
}
|
||||
|
||||
func (s *Structural) IsExclusiveMaximum() bool {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return false
|
||||
}
|
||||
return s.Structural.ValueValidation.ExclusiveMaximum
|
||||
}
|
||||
|
||||
func (s *Structural) MultipleOf() *float64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Structural.ValueValidation.MultipleOf
|
||||
}
|
||||
|
||||
func (s *Structural) MinItems() *int64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Structural.ValueValidation.MinItems
|
||||
}
|
||||
|
||||
func (s *Structural) MaxItems() *int64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
@ -88,6 +137,13 @@ func (s *Structural) MaxItems() *int64 {
|
||||
return s.Structural.ValueValidation.MaxItems
|
||||
}
|
||||
|
||||
func (s *Structural) MinLength() *int64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Structural.ValueValidation.MinLength
|
||||
}
|
||||
|
||||
func (s *Structural) MaxLength() *int64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
@ -95,6 +151,13 @@ func (s *Structural) MaxLength() *int64 {
|
||||
return s.Structural.ValueValidation.MaxLength
|
||||
}
|
||||
|
||||
func (s *Structural) MinProperties() *int64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Structural.ValueValidation.MinProperties
|
||||
}
|
||||
|
||||
func (s *Structural) MaxProperties() *int64 {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
@ -109,6 +172,12 @@ func (s *Structural) Required() []string {
|
||||
return s.Structural.ValueValidation.Required
|
||||
}
|
||||
|
||||
func (s *Structural) UniqueItems() bool {
|
||||
// This field is forbidden in structural schema.
|
||||
// but you can just you x-kubernetes-list-type:set to get around it :)
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Structural) Enum() []any {
|
||||
if s.Structural.ValueValidation == nil {
|
||||
return nil
|
||||
@ -143,10 +212,110 @@ func (s *Structural) XListType() string {
|
||||
return *s.Structural.XListType
|
||||
}
|
||||
|
||||
func (s *Structural) XMapType() string {
|
||||
if s.Structural.XMapType == nil {
|
||||
return ""
|
||||
}
|
||||
return *s.Structural.XMapType
|
||||
}
|
||||
|
||||
func (s *Structural) XListMapKeys() []string {
|
||||
return s.Structural.XListMapKeys
|
||||
}
|
||||
|
||||
func (s *Structural) AllOf() []common.Schema {
|
||||
var res []common.Schema
|
||||
for _, subSchema := range s.Structural.ValueValidation.AllOf {
|
||||
subSchema := subSchema
|
||||
res = append(res, nestedValueValidationToStructural(&subSchema))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Structural) AnyOf() []common.Schema {
|
||||
var res []common.Schema
|
||||
for _, subSchema := range s.Structural.ValueValidation.AnyOf {
|
||||
subSchema := subSchema
|
||||
res = append(res, nestedValueValidationToStructural(&subSchema))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Structural) OneOf() []common.Schema {
|
||||
var res []common.Schema
|
||||
for _, subSchema := range s.Structural.ValueValidation.OneOf {
|
||||
subSchema := subSchema
|
||||
res = append(res, nestedValueValidationToStructural(&subSchema))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Structural) Not() common.Schema {
|
||||
if s.Structural.ValueValidation.Not == nil {
|
||||
return nil
|
||||
}
|
||||
return nestedValueValidationToStructural(s.Structural.ValueValidation.Not)
|
||||
}
|
||||
|
||||
// nestedValueValidationToStructural converts a nested value validation to
|
||||
// an equivalent structural schema instance.
|
||||
//
|
||||
// This lets us avoid needing a separate adaptor for the nested value
|
||||
// validations, and doesn't cost too much since since we are usually exploring the
|
||||
// entire schema anyway.
|
||||
func nestedValueValidationToStructural(nvv *schema.NestedValueValidation) *Structural {
|
||||
var newItems *schema.Structural
|
||||
if nvv.Items != nil {
|
||||
newItems = nestedValueValidationToStructural(nvv.Items).Structural
|
||||
}
|
||||
|
||||
var newProperties map[string]schema.Structural
|
||||
for k, v := range nvv.Properties {
|
||||
if newProperties == nil {
|
||||
newProperties = make(map[string]schema.Structural)
|
||||
}
|
||||
|
||||
v := v
|
||||
newProperties[k] = *nestedValueValidationToStructural(&v).Structural
|
||||
}
|
||||
|
||||
return &Structural{
|
||||
Structural: &schema.Structural{
|
||||
Items: newItems,
|
||||
Properties: newProperties,
|
||||
ValueValidation: &nvv.ValueValidation,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type StructuralValidationRule struct {
|
||||
rule, message, messageExpression, fieldPath string
|
||||
}
|
||||
|
||||
func (s *StructuralValidationRule) Rule() string {
|
||||
return s.rule
|
||||
}
|
||||
func (s *StructuralValidationRule) Message() string {
|
||||
return s.message
|
||||
}
|
||||
func (s *StructuralValidationRule) FieldPath() string {
|
||||
return s.fieldPath
|
||||
}
|
||||
func (s *StructuralValidationRule) MessageExpression() string {
|
||||
return s.messageExpression
|
||||
}
|
||||
|
||||
func (s *Structural) XValidations() []common.ValidationRule {
|
||||
if len(s.Structural.XValidations) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]common.ValidationRule, len(s.Structural.XValidations))
|
||||
for i, v := range s.Structural.XValidations {
|
||||
result[i] = &StructuralValidationRule{rule: v.Rule, message: v.Message, messageExpression: v.MessageExpression, fieldPath: v.FieldPath}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *Structural) WithTypeAndObjectMeta() common.Schema {
|
||||
return &Structural{Structural: WithTypeAndObjectMeta(s.Structural)}
|
||||
}
|
||||
|
@ -56,12 +56,27 @@ type Schema interface {
|
||||
|
||||
// Validations contains OpenAPI validation that the CEL library uses.
|
||||
type Validations interface {
|
||||
Pattern() string
|
||||
Minimum() *float64
|
||||
IsExclusiveMinimum() bool
|
||||
Maximum() *float64
|
||||
IsExclusiveMaximum() bool
|
||||
MultipleOf() *float64
|
||||
MinItems() *int64
|
||||
MaxItems() *int64
|
||||
MinLength() *int64
|
||||
MaxLength() *int64
|
||||
MinProperties() *int64
|
||||
MaxProperties() *int64
|
||||
Required() []string
|
||||
Enum() []any
|
||||
Nullable() bool
|
||||
UniqueItems() bool
|
||||
|
||||
AllOf() []Schema
|
||||
OneOf() []Schema
|
||||
AnyOf() []Schema
|
||||
Not() Schema
|
||||
}
|
||||
|
||||
// KubeExtensions contains Kubernetes-specific extensions to the OpenAPI schema.
|
||||
@ -71,6 +86,16 @@ type KubeExtensions interface {
|
||||
IsXPreserveUnknownFields() bool
|
||||
XListType() string
|
||||
XListMapKeys() []string
|
||||
XMapType() string
|
||||
XValidations() []ValidationRule
|
||||
}
|
||||
|
||||
// ValidationRule represents a single x-kubernetes-validations rule.
|
||||
type ValidationRule interface {
|
||||
Rule() string
|
||||
Message() string
|
||||
MessageExpression() string
|
||||
FieldPath() string
|
||||
}
|
||||
|
||||
// SchemaOrBool contains either a schema or a boolean indicating if the object
|
||||
|
@ -54,6 +54,10 @@ func (s *Schema) Format() string {
|
||||
return s.Schema.Format
|
||||
}
|
||||
|
||||
func (s *Schema) Pattern() string {
|
||||
return s.Schema.Pattern
|
||||
}
|
||||
|
||||
func (s *Schema) Items() common.Schema {
|
||||
if s.Schema.Items == nil || s.Schema.Items.Schema == nil {
|
||||
return nil
|
||||
@ -86,14 +90,50 @@ func (s *Schema) Default() any {
|
||||
return s.Schema.Default
|
||||
}
|
||||
|
||||
func (s *Schema) Minimum() *float64 {
|
||||
return s.Schema.Minimum
|
||||
}
|
||||
|
||||
func (s *Schema) IsExclusiveMinimum() bool {
|
||||
return s.Schema.ExclusiveMinimum
|
||||
}
|
||||
|
||||
func (s *Schema) Maximum() *float64 {
|
||||
return s.Schema.Maximum
|
||||
}
|
||||
|
||||
func (s *Schema) IsExclusiveMaximum() bool {
|
||||
return s.Schema.ExclusiveMaximum
|
||||
}
|
||||
|
||||
func (s *Schema) MultipleOf() *float64 {
|
||||
return s.Schema.MultipleOf
|
||||
}
|
||||
|
||||
func (s *Schema) UniqueItems() bool {
|
||||
return s.Schema.UniqueItems
|
||||
}
|
||||
|
||||
func (s *Schema) MinItems() *int64 {
|
||||
return s.Schema.MinItems
|
||||
}
|
||||
|
||||
func (s *Schema) MaxItems() *int64 {
|
||||
return s.Schema.MaxItems
|
||||
}
|
||||
|
||||
func (s *Schema) MinLength() *int64 {
|
||||
return s.Schema.MinLength
|
||||
}
|
||||
|
||||
func (s *Schema) MaxLength() *int64 {
|
||||
return s.Schema.MaxLength
|
||||
}
|
||||
|
||||
func (s *Schema) MinProperties() *int64 {
|
||||
return s.Schema.MinProperties
|
||||
}
|
||||
|
||||
func (s *Schema) MaxProperties() *int64 {
|
||||
return s.Schema.MaxProperties
|
||||
}
|
||||
@ -110,6 +150,40 @@ func (s *Schema) Nullable() bool {
|
||||
return s.Schema.Nullable
|
||||
}
|
||||
|
||||
func (s *Schema) AllOf() []common.Schema {
|
||||
var res []common.Schema
|
||||
for _, nestedSchema := range s.Schema.AllOf {
|
||||
nestedSchema := nestedSchema
|
||||
res = append(res, &Schema{&nestedSchema})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Schema) AnyOf() []common.Schema {
|
||||
var res []common.Schema
|
||||
for _, nestedSchema := range s.Schema.AnyOf {
|
||||
nestedSchema := nestedSchema
|
||||
res = append(res, &Schema{&nestedSchema})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Schema) OneOf() []common.Schema {
|
||||
var res []common.Schema
|
||||
for _, nestedSchema := range s.Schema.OneOf {
|
||||
nestedSchema := nestedSchema
|
||||
res = append(res, &Schema{&nestedSchema})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Schema) Not() common.Schema {
|
||||
if s.Schema.Not == nil {
|
||||
return nil
|
||||
}
|
||||
return &Schema{s.Schema.Not}
|
||||
}
|
||||
|
||||
func (s *Schema) IsXIntOrString() bool {
|
||||
return isXIntOrString(s.Schema)
|
||||
}
|
||||
@ -126,10 +200,18 @@ func (s *Schema) XListType() string {
|
||||
return getXListType(s.Schema)
|
||||
}
|
||||
|
||||
func (s *Schema) XMapType() string {
|
||||
return getXMapType(s.Schema)
|
||||
}
|
||||
|
||||
func (s *Schema) XListMapKeys() []string {
|
||||
return getXListMapKeys(s.Schema)
|
||||
}
|
||||
|
||||
func (s *Schema) XValidations() []common.ValidationRule {
|
||||
return getXValidations(s.Schema)
|
||||
}
|
||||
|
||||
func (s *Schema) WithTypeAndObjectMeta() common.Schema {
|
||||
return &Schema{common.WithTypeAndObjectMeta(s.Schema)}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package openapi
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apiserver/pkg/cel/common"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
@ -47,6 +48,11 @@ func getXListType(schema *spec.Schema) string {
|
||||
return s
|
||||
}
|
||||
|
||||
func getXMapType(schema *spec.Schema) string {
|
||||
s, _ := schema.Extensions.GetString(extMapType)
|
||||
return s
|
||||
}
|
||||
|
||||
func getXListMapKeys(schema *spec.Schema) []string {
|
||||
mapKeys, ok := schema.Extensions.GetStringSlice(extListMapKeys)
|
||||
if !ok {
|
||||
@ -55,8 +61,47 @@ func getXListMapKeys(schema *spec.Schema) []string {
|
||||
return mapKeys
|
||||
}
|
||||
|
||||
type ValidationRule struct {
|
||||
RuleField string `json:"rule"`
|
||||
MessageField string `json:"message"`
|
||||
MessageExpressionField string `json:"messageExpression"`
|
||||
PathField string `json:"fieldPath"`
|
||||
}
|
||||
|
||||
func (v ValidationRule) Rule() string {
|
||||
return v.RuleField
|
||||
}
|
||||
|
||||
func (v ValidationRule) Message() string {
|
||||
return v.MessageField
|
||||
}
|
||||
|
||||
func (v ValidationRule) FieldPath() string {
|
||||
return v.PathField
|
||||
}
|
||||
|
||||
func (v ValidationRule) MessageExpression() string {
|
||||
return v.MessageExpressionField
|
||||
}
|
||||
|
||||
// TODO: simplify
|
||||
func getXValidations(schema *spec.Schema) []common.ValidationRule {
|
||||
var rules []ValidationRule
|
||||
err := schema.Extensions.GetObject(extValidations, &rules)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
results := make([]common.ValidationRule, len(rules))
|
||||
for i, rule := range rules {
|
||||
results[i] = rule
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
const extIntOrString = "x-kubernetes-int-or-string"
|
||||
const extEmbeddedResource = "x-kubernetes-embedded-resource"
|
||||
const extPreserveUnknownFields = "x-kubernetes-preserve-unknown-fields"
|
||||
const extListType = "x-kubernetes-list-type"
|
||||
const extMapType = "x-kubernetes-map-type"
|
||||
const extListMapKeys = "x-kubernetes-list-map-keys"
|
||||
const extValidations = "x-kubernetes-validations"
|
||||
|
Loading…
Reference in New Issue
Block a user