...

Source file src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go

Documentation: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package apiextensions
    18  
    19  // FieldValueErrorReason is a machine-readable value providing more detail about why a field failed the validation.
    20  // +enum
    21  type FieldValueErrorReason string
    22  
    23  const (
    24  	// FieldValueRequired is used to report required values that are not
    25  	// provided (e.g. empty strings, null values, or empty arrays).
    26  	FieldValueRequired FieldValueErrorReason = "FieldValueRequired"
    27  	// FieldValueDuplicate is used to report collisions of values that must be
    28  	// unique (e.g. unique IDs).
    29  	FieldValueDuplicate FieldValueErrorReason = "FieldValueDuplicate"
    30  	// FieldValueInvalid is used to report malformed values (e.g. failed regex
    31  	// match, too long, out of bounds).
    32  	FieldValueInvalid FieldValueErrorReason = "FieldValueInvalid"
    33  	// FieldValueForbidden is used to report valid (as per formatting rules)
    34  	// values which would be accepted under some conditions, but which are not
    35  	// permitted by the current conditions (such as security policy).
    36  	FieldValueForbidden FieldValueErrorReason = "FieldValueForbidden"
    37  )
    38  
    39  // JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).
    40  type JSONSchemaProps struct {
    41  	ID                   string
    42  	Schema               JSONSchemaURL
    43  	Ref                  *string
    44  	Description          string
    45  	Type                 string
    46  	Nullable             bool
    47  	Format               string
    48  	Title                string
    49  	Default              *JSON
    50  	Maximum              *float64
    51  	ExclusiveMaximum     bool
    52  	Minimum              *float64
    53  	ExclusiveMinimum     bool
    54  	MaxLength            *int64
    55  	MinLength            *int64
    56  	Pattern              string
    57  	MaxItems             *int64
    58  	MinItems             *int64
    59  	UniqueItems          bool
    60  	MultipleOf           *float64
    61  	Enum                 []JSON
    62  	MaxProperties        *int64
    63  	MinProperties        *int64
    64  	Required             []string
    65  	Items                *JSONSchemaPropsOrArray
    66  	AllOf                []JSONSchemaProps
    67  	OneOf                []JSONSchemaProps
    68  	AnyOf                []JSONSchemaProps
    69  	Not                  *JSONSchemaProps
    70  	Properties           map[string]JSONSchemaProps
    71  	AdditionalProperties *JSONSchemaPropsOrBool
    72  	PatternProperties    map[string]JSONSchemaProps
    73  	Dependencies         JSONSchemaDependencies
    74  	AdditionalItems      *JSONSchemaPropsOrBool
    75  	Definitions          JSONSchemaDefinitions
    76  	ExternalDocs         *ExternalDocumentation
    77  	Example              *JSON
    78  
    79  	// x-kubernetes-preserve-unknown-fields stops the API server
    80  	// decoding step from pruning fields which are not specified
    81  	// in the validation schema. This affects fields recursively,
    82  	// but switches back to normal pruning behaviour if nested
    83  	// properties or additionalProperties are specified in the schema.
    84  	// This can either be true or undefined. False is forbidden.
    85  	XPreserveUnknownFields *bool
    86  
    87  	// x-kubernetes-embedded-resource defines that the value is an
    88  	// embedded Kubernetes runtime.Object, with TypeMeta and
    89  	// ObjectMeta. The type must be object. It is allowed to further
    90  	// restrict the embedded object. Both ObjectMeta and TypeMeta
    91  	// are validated automatically. x-kubernetes-preserve-unknown-fields
    92  	// must be true.
    93  	XEmbeddedResource bool
    94  
    95  	// x-kubernetes-int-or-string specifies that this value is
    96  	// either an integer or a string. If this is true, an empty
    97  	// type is allowed and type as child of anyOf is permitted
    98  	// if following one of the following patterns:
    99  	//
   100  	// 1) anyOf:
   101  	//    - type: integer
   102  	//    - type: string
   103  	// 2) allOf:
   104  	//    - anyOf:
   105  	//      - type: integer
   106  	//      - type: string
   107  	//    - ... zero or more
   108  	XIntOrString bool
   109  
   110  	// x-kubernetes-list-map-keys annotates an array with the x-kubernetes-list-type `map` by specifying the keys used
   111  	// as the index of the map.
   112  	//
   113  	// This tag MUST only be used on lists that have the "x-kubernetes-list-type"
   114  	// extension set to "map". Also, the values specified for this attribute must
   115  	// be a scalar typed field of the child structure (no nesting is supported).
   116  	XListMapKeys []string
   117  
   118  	// x-kubernetes-list-type annotates an array to further describe its topology.
   119  	// This extension must only be used on lists and may have 3 possible values:
   120  	//
   121  	// 1) `atomic`: the list is treated as a single entity, like a scalar.
   122  	//      Atomic lists will be entirely replaced when updated. This extension
   123  	//      may be used on any type of list (struct, scalar, ...).
   124  	// 2) `set`:
   125  	//      Sets are lists that must not have multiple items with the same value. Each
   126  	//      value must be a scalar, an object with x-kubernetes-map-type `atomic` or an
   127  	//      array with x-kubernetes-list-type `atomic`.
   128  	// 3) `map`:
   129  	//      These lists are like maps in that their elements have a non-index key
   130  	//      used to identify them. Order is preserved upon merge. The map tag
   131  	//      must only be used on a list with elements of type object.
   132  	XListType *string
   133  
   134  	// x-kubernetes-map-type annotates an object to further describe its topology.
   135  	// This extension must only be used when type is object and may have 2 possible values:
   136  	//
   137  	// 1) `granular`:
   138  	//      These maps are actual maps (key-value pairs) and each fields are independent
   139  	//      from each other (they can each be manipulated by separate actors). This is
   140  	//      the default behaviour for all maps.
   141  	// 2) `atomic`: the list is treated as a single entity, like a scalar.
   142  	//      Atomic maps will be entirely replaced when updated.
   143  	// +optional
   144  	XMapType *string
   145  
   146  	// x-kubernetes-validations -kubernetes-validations describes a list of validation rules written in the CEL expression language.
   147  	// This field is an alpha-level. Using this field requires the feature gate `CustomResourceValidationExpressions` to be enabled.
   148  	// +patchMergeKey=rule
   149  	// +patchStrategy=merge
   150  	// +listType=map
   151  	// +listMapKey=rule
   152  	XValidations ValidationRules
   153  }
   154  
   155  // ValidationRules describes a list of validation rules written in the CEL expression language.
   156  type ValidationRules []ValidationRule
   157  
   158  // ValidationRule describes a validation rule written in the CEL expression language.
   159  type ValidationRule struct {
   160  	// Rule represents the expression which will be evaluated by CEL.
   161  	// ref: https://github.com/google/cel-spec
   162  	// The Rule is scoped to the location of the x-kubernetes-validations extension in the schema.
   163  	// The `self` variable in the CEL expression is bound to the scoped value.
   164  	// Example:
   165  	// - Rule scoped to the root of a resource with a status subresource: {"rule": "self.status.actual <= self.spec.maxDesired"}
   166  	//
   167  	// If the Rule is scoped to an object with properties, the accessible properties of the object are field selectable
   168  	// via `self.field` and field presence can be checked via `has(self.field)`. Null valued fields are treated as
   169  	// absent fields in CEL expressions.
   170  	// If the Rule is scoped to an object with additionalProperties (i.e. a map) the value of the map
   171  	// are accessible via `self[mapKey]`, map containment can be checked via `mapKey in self` and all entries of the map
   172  	// are accessible via CEL macros and functions such as `self.all(...)`.
   173  	// If the Rule is scoped to an array, the elements of the array are accessible via `self[i]` and also by macros and
   174  	// functions.
   175  	// If the Rule is scoped to a scalar, `self` is bound to the scalar value.
   176  	// Examples:
   177  	// - Rule scoped to a map of objects: {"rule": "self.components['Widget'].priority < 10"}
   178  	// - Rule scoped to a list of integers: {"rule": "self.values.all(value, value >= 0 && value < 100)"}
   179  	// - Rule scoped to a string value: {"rule": "self.startsWith('kube')"}
   180  	//
   181  	// The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the
   182  	// object and from any x-kubernetes-embedded-resource annotated objects. No other metadata properties are accessible.
   183  	//
   184  	// Unknown data preserved in custom resources via x-kubernetes-preserve-unknown-fields is not accessible in CEL
   185  	// expressions. This includes:
   186  	// - Unknown field values that are preserved by object schemas with x-kubernetes-preserve-unknown-fields.
   187  	// - Object properties where the property schema is of an "unknown type". An "unknown type" is recursively defined as:
   188  	//   - A schema with no type and x-kubernetes-preserve-unknown-fields set to true
   189  	//   - An array where the items schema is of an "unknown type"
   190  	//   - An object where the additionalProperties schema is of an "unknown type"
   191  	//
   192  	// Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible.
   193  	// Accessible property names are escaped according to the following rules when accessed in the expression:
   194  	// - '__' escapes to '__underscores__'
   195  	// - '.' escapes to '__dot__'
   196  	// - '-' escapes to '__dash__'
   197  	// - '/' escapes to '__slash__'
   198  	// - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:
   199  	//	  "true", "false", "null", "in", "as", "break", "const", "continue", "else", "for", "function", "if",
   200  	//	  "import", "let", "loop", "package", "namespace", "return".
   201  	// Examples:
   202  	//   - Rule accessing a property named "namespace": {"rule": "self.__namespace__ > 0"}
   203  	//   - Rule accessing a property named "x-prop": {"rule": "self.x__dash__prop > 0"}
   204  	//   - Rule accessing a property named "redact__d": {"rule": "self.redact__underscores__d > 0"}
   205  	//
   206  	// Equality on arrays with x-kubernetes-list-type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1].
   207  	// Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:
   208  	//   - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and
   209  	//     non-intersecting elements in `Y` are appended, retaining their partial order.
   210  	//   - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values
   211  	//     are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with
   212  	//     non-intersecting keys are appended, retaining their partial order.
   213  	//
   214  	// If `rule` makes use of the `oldSelf` variable it is implicitly a
   215  	// `transition rule`.
   216  	//
   217  	// By default, the `oldSelf` variable is the same type as `self`.
   218  	// When `optionalOldSelf` is true, the `oldSelf` variable is a CEL optional
   219  	//  variable whose value() is the same type as `self`.
   220  	// See the documentation for the `optionalOldSelf` field for details.
   221  	//
   222  	// Transition rules by default are applied only on UPDATE requests and are
   223  	// skipped if an old value could not be found. You can opt a transition
   224  	// rule into unconditional evaluation by setting `optionalOldSelf` to true.
   225  	//
   226  	Rule string
   227  	// Message represents the message displayed when validation fails. The message is required if the Rule contains
   228  	// line breaks. The message must not contain line breaks.
   229  	// If unset, the message is "failed rule: {Rule}".
   230  	// e.g. "must be a URL with the host matching spec.host"
   231  	Message string
   232  	// MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails.
   233  	// Since messageExpression is used as a failure message, it must evaluate to a string.
   234  	// If both message and messageExpression are present on a rule, then messageExpression will be used if validation
   235  	// fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced
   236  	// as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string
   237  	// that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and
   238  	// the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged.
   239  	// messageExpression has access to all the same variables as the rule; the only difference is the return type.
   240  	// Example:
   241  	// "x must be less than max ("+string(self.max)+")"
   242  	// +optional
   243  	MessageExpression string
   244  	// reason provides a machine-readable validation failure reason that is returned to the caller when a request fails this validation rule.
   245  	// The HTTP status code returned to the caller will match the reason of the reason of the first failed validation rule.
   246  	// The currently supported reasons are: "FieldValueInvalid", "FieldValueForbidden", "FieldValueRequired", "FieldValueDuplicate".
   247  	// If not set, default to use "FieldValueInvalid".
   248  	// All future added reasons must be accepted by clients when reading this value and unknown reasons should be treated as FieldValueInvalid.
   249  	// +optional
   250  	Reason *FieldValueErrorReason
   251  	// fieldPath represents the field path returned when the validation fails.
   252  	// It must be a relative JSON path (i.e. with array notation) scoped to the location of this x-kubernetes-validations extension in the schema and refer to an existing field.
   253  	// e.g. when validation checks if a specific attribute `foo` under a map `testMap`, the fieldPath could be set to `.testMap.foo`
   254  	// If the validation checks two lists must have unique attributes, the fieldPath could be set to either of the list: e.g. `.testList`
   255  	// It does not support list numeric index.
   256  	// It supports child operation to refer to an existing field currently. Refer to [JSONPath support in Kubernetes](https://kubernetes.io/docs/reference/kubectl/jsonpath/) for more info.
   257  	// Numeric index of array is not supported.
   258  	// For field name which contains special characters, use `['specialName']` to refer the field name.
   259  	// e.g. for attribute `foo.34$` appears in a list `testList`, the fieldPath could be set to `.testList['foo.34$']`
   260  	// +optional
   261  	FieldPath string
   262  
   263  	// optionalOldSelf is used to opt a transition rule into evaluation
   264  	// even when the object is first created, or if the old object is
   265  	// missing the value.
   266  	//
   267  	// When enabled `oldSelf` will be a CEL optional whose value will be
   268  	// `None` if there is no old value, or when the object is initially created.
   269  	//
   270  	// You may check for presence of oldSelf using `oldSelf.hasValue()` and
   271  	// unwrap it after checking using `oldSelf.value()`. Check the CEL
   272  	// documentation for Optional types for more information:
   273  	// https://pkg.go.dev/github.com/google/cel-go/cel#OptionalTypes
   274  	//
   275  	// May not be set unless `oldSelf` is used in `rule`.
   276  	//
   277  	// +featureGate=CRDValidationRatcheting
   278  	// +optional
   279  	OptionalOldSelf *bool
   280  }
   281  
   282  // JSON represents any valid JSON value.
   283  // These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil.
   284  type JSON interface{}
   285  
   286  // JSONSchemaURL represents a schema url.
   287  type JSONSchemaURL string
   288  
   289  // JSONSchemaPropsOrArray represents a value that can either be a JSONSchemaProps
   290  // or an array of JSONSchemaProps. Mainly here for serialization purposes.
   291  type JSONSchemaPropsOrArray struct {
   292  	Schema      *JSONSchemaProps
   293  	JSONSchemas []JSONSchemaProps
   294  }
   295  
   296  // JSONSchemaPropsOrBool represents JSONSchemaProps or a boolean value.
   297  // Defaults to true for the boolean property.
   298  type JSONSchemaPropsOrBool struct {
   299  	Allows bool
   300  	Schema *JSONSchemaProps
   301  }
   302  
   303  // JSONSchemaDependencies represent a dependencies property.
   304  type JSONSchemaDependencies map[string]JSONSchemaPropsOrStringArray
   305  
   306  // JSONSchemaPropsOrStringArray represents a JSONSchemaProps or a string array.
   307  type JSONSchemaPropsOrStringArray struct {
   308  	Schema   *JSONSchemaProps
   309  	Property []string
   310  }
   311  
   312  // JSONSchemaDefinitions contains the models explicitly defined in this spec.
   313  type JSONSchemaDefinitions map[string]JSONSchemaProps
   314  
   315  // ExternalDocumentation allows referencing an external resource for extended documentation.
   316  type ExternalDocumentation struct {
   317  	Description string
   318  	URL         string
   319  }
   320  

View as plain text