1 /* 2 Copyright 2019 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 schema 18 19 import ( 20 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 21 "k8s.io/apimachinery/pkg/runtime" 22 ) 23 24 // +k8s:deepcopy-gen=true 25 26 // Structural represents a structural schema. 27 type Structural struct { 28 Items *Structural 29 Properties map[string]Structural 30 31 Generic 32 Extensions 33 34 ValueValidation *ValueValidation 35 } 36 37 // +k8s:deepcopy-gen=true 38 39 // StructuralOrBool is either a structural schema or a boolean. 40 type StructuralOrBool struct { 41 Structural *Structural 42 Bool bool 43 } 44 45 // +k8s:deepcopy-gen=true 46 47 // Generic contains the generic schema fields not allowed in value validation. 48 type Generic struct { 49 Description string 50 // type specifies the type of a value. 51 // It can be object, array, number, integer, boolean, string. 52 // It is optional only if x-kubernetes-preserve-unknown-fields 53 // or x-kubernetes-int-or-string is true. 54 Type string 55 Title string 56 Default JSON 57 AdditionalProperties *StructuralOrBool 58 Nullable bool 59 } 60 61 // +k8s:deepcopy-gen=true 62 63 // Extensions contains the Kubernetes OpenAPI v3 vendor extensions. 64 type Extensions struct { 65 // x-kubernetes-preserve-unknown-fields stops the API server 66 // decoding step from pruning fields which are not specified 67 // in the validation schema. This affects fields recursively, 68 // but switches back to normal pruning behaviour if nested 69 // properties or additionalProperties are specified in the schema. 70 // False means that the pruning behaviour is inherited from the parent. 71 // False does not mean to activate pruning. 72 XPreserveUnknownFields bool 73 74 // x-kubernetes-embedded-resource defines that the value is an 75 // embedded Kubernetes runtime.Object, with TypeMeta and 76 // ObjectMeta. The type must be object. It is allowed to further 77 // restrict the embedded object. Both ObjectMeta and TypeMeta 78 // are validated automatically. x-kubernetes-preserve-unknown-fields 79 // must be true. 80 XEmbeddedResource bool 81 82 // x-kubernetes-int-or-string specifies that this value is 83 // either an integer or a string. If this is true, an empty 84 // type is allowed and type as child of anyOf is permitted 85 // if following one of the following patterns: 86 // 87 // 1) anyOf: 88 // - type: integer 89 // - type: string 90 // 2) allOf: 91 // - anyOf: 92 // - type: integer 93 // - type: string 94 // - ... zero or more 95 XIntOrString bool 96 97 // x-kubernetes-list-map-keys annotates lists with the x-kubernetes-list-type `map` by specifying the keys used 98 // as the index of the map. 99 // 100 // This tag MUST only be used on lists that have the "x-kubernetes-list-type" 101 // extension set to "map". Also, the values specified for this attribute must 102 // be a scalar typed field of the child structure (no nesting is supported). 103 XListMapKeys []string 104 105 // x-kubernetes-list-type annotates a list to further describe its topology. 106 // This extension must only be used on lists and may have 3 possible values: 107 // 108 // 1) `atomic`: the list is treated as a single entity, like a scalar. 109 // Atomic lists will be entirely replaced when updated. This extension 110 // may be used on any type of list (struct, scalar, ...). 111 // 2) `set`: 112 // Sets are lists that must not have multiple items with the same value. Each 113 // value must be a scalar (or another atomic type). 114 // 3) `map`: 115 // These lists are like maps in that their elements have a non-index key 116 // used to identify them. Order is preserved upon merge. The map tag 117 // must only be used on a list with elements of type object. 118 XListType *string 119 120 // x-kubernetes-map-type annotates an object to further describe its topology. 121 // This extension must only be used when type is object and may have 2 possible values: 122 // 123 // 1) `granular`: 124 // These maps are actual maps (key-value pairs) and each fields are independent 125 // from each other (they can each be manipulated by separate actors). This is 126 // the default behaviour for all maps. 127 // 2) `atomic`: the list is treated as a single entity, like a scalar. 128 // Atomic maps will be entirely replaced when updated. 129 // +optional 130 XMapType *string 131 132 // x-kubernetes-validations describes a list of validation rules for expression validation. 133 // Use the v1 struct since this gets serialized as an extension. 134 XValidations apiextensionsv1.ValidationRules 135 } 136 137 // +k8s:deepcopy-gen=true 138 139 // ValueValidation contains all schema fields not contributing to the structure of the schema. 140 type ValueValidation struct { 141 Format string 142 Maximum *float64 143 ExclusiveMaximum bool 144 Minimum *float64 145 ExclusiveMinimum bool 146 MaxLength *int64 147 MinLength *int64 148 Pattern string 149 MaxItems *int64 150 MinItems *int64 151 UniqueItems bool 152 MultipleOf *float64 153 Enum []JSON 154 MaxProperties *int64 155 MinProperties *int64 156 Required []string 157 AllOf []NestedValueValidation 158 OneOf []NestedValueValidation 159 AnyOf []NestedValueValidation 160 Not *NestedValueValidation 161 } 162 163 // +k8s:deepcopy-gen=true 164 165 // NestedValueValidation contains value validations, items and properties usable when nested 166 // under a logical junctor, and catch all structs for generic and vendor extensions schema fields. 167 type NestedValueValidation struct { 168 ValueValidation 169 170 Items *NestedValueValidation 171 Properties map[string]NestedValueValidation 172 173 // Anything set in the following will make the scheme 174 // non-structural, with the exception of these two patterns if 175 // x-kubernetes-int-or-string is true: 176 // 177 // 1) anyOf: 178 // - type: integer 179 // - type: string 180 // 2) allOf: 181 // - anyOf: 182 // - type: integer 183 // - type: string 184 // - ... zero or more 185 ForbiddenGenerics Generic 186 ForbiddenExtensions Extensions 187 } 188 189 // JSON wraps an arbitrary JSON value to be able to implement deepcopy. 190 type JSON struct { 191 Object interface{} 192 } 193 194 // DeepCopy creates a deep copy of the wrapped JSON value. 195 func (j JSON) DeepCopy() JSON { 196 return JSON{runtime.DeepCopyJSONValue(j.Object)} 197 } 198 199 // DeepCopyInto creates a deep copy of the wrapped JSON value and stores it in into. 200 func (j JSON) DeepCopyInto(into *JSON) { 201 into.Object = runtime.DeepCopyJSONValue(j.Object) 202 } 203