1
16
17 package schema
18
19 import (
20 "fmt"
21 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
22 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
23 )
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 func NewStructural(s *apiextensions.JSONSchemaProps) (*Structural, error) {
42 if s == nil {
43 return nil, nil
44 }
45
46 if err := validateUnsupportedFields(s); err != nil {
47 return nil, err
48 }
49
50 vv, err := newValueValidation(s)
51 if err != nil {
52 return nil, err
53 }
54
55 g, err := newGenerics(s)
56 if err != nil {
57 return nil, err
58 }
59
60 x, err := newExtensions(s)
61 if err != nil {
62 return nil, err
63 }
64
65 ss := &Structural{
66 Generic: *g,
67 Extensions: *x,
68 ValueValidation: vv,
69 }
70
71 if s.Items != nil {
72 if len(s.Items.JSONSchemas) > 0 {
73
74 return nil, fmt.Errorf("OpenAPIV3Schema 'items' must be a schema, but is an array")
75 }
76 item, err := NewStructural(s.Items.Schema)
77 if err != nil {
78 return nil, err
79 }
80 ss.Items = item
81 }
82
83 if len(s.Properties) > 0 {
84 ss.Properties = make(map[string]Structural, len(s.Properties))
85 for k, x := range s.Properties {
86 fld, err := NewStructural(&x)
87 if err != nil {
88 return nil, err
89 }
90 ss.Properties[k] = *fld
91 }
92 }
93
94 return ss, nil
95 }
96
97 func newGenerics(s *apiextensions.JSONSchemaProps) (*Generic, error) {
98 if s == nil {
99 return nil, nil
100 }
101 g := &Generic{
102 Type: s.Type,
103 Description: s.Description,
104 Title: s.Title,
105 Nullable: s.Nullable,
106 }
107 if s.Default != nil {
108 g.Default = JSON{interface{}(*s.Default)}
109 }
110
111 if s.AdditionalProperties != nil {
112 if s.AdditionalProperties.Schema != nil {
113 ss, err := NewStructural(s.AdditionalProperties.Schema)
114 if err != nil {
115 return nil, err
116 }
117 g.AdditionalProperties = &StructuralOrBool{Structural: ss, Bool: true}
118 } else {
119 g.AdditionalProperties = &StructuralOrBool{Bool: s.AdditionalProperties.Allows}
120 }
121 }
122
123 return g, nil
124 }
125
126 func newValueValidation(s *apiextensions.JSONSchemaProps) (*ValueValidation, error) {
127 if s == nil {
128 return nil, nil
129 }
130 not, err := newNestedValueValidation(s.Not)
131 if err != nil {
132 return nil, err
133 }
134 v := &ValueValidation{
135 Format: s.Format,
136 Maximum: s.Maximum,
137 ExclusiveMaximum: s.ExclusiveMaximum,
138 Minimum: s.Minimum,
139 ExclusiveMinimum: s.ExclusiveMinimum,
140 MaxLength: s.MaxLength,
141 MinLength: s.MinLength,
142 Pattern: s.Pattern,
143 MaxItems: s.MaxItems,
144 MinItems: s.MinItems,
145 UniqueItems: s.UniqueItems,
146 MultipleOf: s.MultipleOf,
147 MaxProperties: s.MaxProperties,
148 MinProperties: s.MinProperties,
149 Required: s.Required,
150 Not: not,
151 }
152
153 for _, e := range s.Enum {
154 v.Enum = append(v.Enum, JSON{e})
155 }
156
157 for _, x := range s.AllOf {
158 clause, err := newNestedValueValidation(&x)
159 if err != nil {
160 return nil, err
161 }
162 v.AllOf = append(v.AllOf, *clause)
163 }
164
165 for _, x := range s.AnyOf {
166 clause, err := newNestedValueValidation(&x)
167 if err != nil {
168 return nil, err
169 }
170 v.AnyOf = append(v.AnyOf, *clause)
171 }
172
173 for _, x := range s.OneOf {
174 clause, err := newNestedValueValidation(&x)
175 if err != nil {
176 return nil, err
177 }
178 v.OneOf = append(v.OneOf, *clause)
179 }
180
181 return v, nil
182 }
183
184 func newNestedValueValidation(s *apiextensions.JSONSchemaProps) (*NestedValueValidation, error) {
185 if s == nil {
186 return nil, nil
187 }
188
189 if err := validateUnsupportedFields(s); err != nil {
190 return nil, err
191 }
192
193 vv, err := newValueValidation(s)
194 if err != nil {
195 return nil, err
196 }
197
198 g, err := newGenerics(s)
199 if err != nil {
200 return nil, err
201 }
202
203 x, err := newExtensions(s)
204 if err != nil {
205 return nil, err
206 }
207
208 v := &NestedValueValidation{
209 ValueValidation: *vv,
210 ForbiddenGenerics: *g,
211 ForbiddenExtensions: *x,
212 }
213
214 if s.Items != nil {
215 if len(s.Items.JSONSchemas) > 0 {
216
217 return nil, fmt.Errorf("OpenAPIV3Schema 'items' must be a schema, but is an array")
218 }
219 nvv, err := newNestedValueValidation(s.Items.Schema)
220 if err != nil {
221 return nil, err
222 }
223 v.Items = nvv
224 }
225 if s.Properties != nil {
226 v.Properties = make(map[string]NestedValueValidation, len(s.Properties))
227 for k, x := range s.Properties {
228 nvv, err := newNestedValueValidation(&x)
229 if err != nil {
230 return nil, err
231 }
232 v.Properties[k] = *nvv
233 }
234 }
235
236 return v, nil
237 }
238
239 func newExtensions(s *apiextensions.JSONSchemaProps) (*Extensions, error) {
240 if s == nil {
241 return nil, nil
242 }
243
244 ret := &Extensions{
245 XEmbeddedResource: s.XEmbeddedResource,
246 XIntOrString: s.XIntOrString,
247 XListMapKeys: s.XListMapKeys,
248 XListType: s.XListType,
249 XMapType: s.XMapType,
250 }
251 if err := apiextensionsv1.Convert_apiextensions_ValidationRules_To_v1_ValidationRules(&s.XValidations, &ret.XValidations, nil); err != nil {
252 return nil, err
253 }
254
255 if s.XPreserveUnknownFields != nil {
256 if !*s.XPreserveUnknownFields {
257 return nil, fmt.Errorf("internal error: 'x-kubernetes-preserve-unknown-fields' must be true or undefined")
258 }
259 ret.XPreserveUnknownFields = true
260 }
261
262 return ret, nil
263 }
264
265
266 func validateUnsupportedFields(s *apiextensions.JSONSchemaProps) error {
267 if len(s.ID) > 0 {
268 return fmt.Errorf("OpenAPIV3Schema 'id' is not supported")
269 }
270 if len(s.Schema) > 0 {
271 return fmt.Errorf("OpenAPIV3Schema 'schema' is not supported")
272 }
273 if s.Ref != nil && len(*s.Ref) > 0 {
274 return fmt.Errorf("OpenAPIV3Schema '$ref' is not supported")
275 }
276 if len(s.PatternProperties) > 0 {
277 return fmt.Errorf("OpenAPIV3Schema 'patternProperties' is not supported")
278 }
279 if len(s.Dependencies) > 0 {
280 return fmt.Errorf("OpenAPIV3Schema 'dependencies' is not supported")
281 }
282 if s.AdditionalItems != nil {
283 return fmt.Errorf("OpenAPIV3Schema 'additionalItems' is not supported")
284 }
285 if len(s.Definitions) > 0 {
286 return fmt.Errorf("OpenAPIV3Schema 'definitions' is not supported")
287 }
288
289 return nil
290 }
291
View as plain text