k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/handler/default_pruning.go (about)

     1  /*
     2  Copyright 2020 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 handler
    18  
    19  import "k8s.io/kube-openapi/pkg/validation/spec"
    20  
    21  // PruneDefaults remove all the defaults recursively from all the
    22  // schemas in the definitions, and does not modify the definitions in
    23  // place.
    24  func PruneDefaults(definitions spec.Definitions) spec.Definitions {
    25  	definitionsCloned := false
    26  	for k, v := range definitions {
    27  		if s := PruneDefaultsSchema(&v); s != &v {
    28  			if !definitionsCloned {
    29  				definitionsCloned = true
    30  				orig := definitions
    31  				definitions = make(spec.Definitions, len(orig))
    32  				for k2, v2 := range orig {
    33  					definitions[k2] = v2
    34  				}
    35  			}
    36  			definitions[k] = *s
    37  		}
    38  	}
    39  	return definitions
    40  }
    41  
    42  // PruneDefaultsSchema remove all the defaults recursively from the
    43  // schema in place.
    44  func PruneDefaultsSchema(schema *spec.Schema) *spec.Schema {
    45  	if schema == nil {
    46  		return nil
    47  	}
    48  
    49  	orig := schema
    50  	clone := func() {
    51  		if orig == schema {
    52  			schema = &spec.Schema{}
    53  			*schema = *orig
    54  		}
    55  	}
    56  
    57  	if schema.Default != nil {
    58  		clone()
    59  		schema.Default = nil
    60  	}
    61  
    62  	definitionsCloned := false
    63  	for k, v := range schema.Definitions {
    64  		if s := PruneDefaultsSchema(&v); s != &v {
    65  			if !definitionsCloned {
    66  				definitionsCloned = true
    67  				clone()
    68  				schema.Definitions = make(spec.Definitions, len(orig.Definitions))
    69  				for k2, v2 := range orig.Definitions {
    70  					schema.Definitions[k2] = v2
    71  				}
    72  			}
    73  			schema.Definitions[k] = *s
    74  		}
    75  	}
    76  
    77  	propertiesCloned := false
    78  	for k, v := range schema.Properties {
    79  		if s := PruneDefaultsSchema(&v); s != &v {
    80  			if !propertiesCloned {
    81  				propertiesCloned = true
    82  				clone()
    83  				schema.Properties = make(map[string]spec.Schema, len(orig.Properties))
    84  				for k2, v2 := range orig.Properties {
    85  					schema.Properties[k2] = v2
    86  				}
    87  			}
    88  			schema.Properties[k] = *s
    89  		}
    90  	}
    91  
    92  	patternPropertiesCloned := false
    93  	for k, v := range schema.PatternProperties {
    94  		if s := PruneDefaultsSchema(&v); s != &v {
    95  			if !patternPropertiesCloned {
    96  				patternPropertiesCloned = true
    97  				clone()
    98  				schema.PatternProperties = make(map[string]spec.Schema, len(orig.PatternProperties))
    99  				for k2, v2 := range orig.PatternProperties {
   100  					schema.PatternProperties[k2] = v2
   101  				}
   102  			}
   103  			schema.PatternProperties[k] = *s
   104  		}
   105  	}
   106  
   107  	dependenciesCloned := false
   108  	for k, v := range schema.Dependencies {
   109  		if s := PruneDefaultsSchema(v.Schema); s != v.Schema {
   110  			if !dependenciesCloned {
   111  				dependenciesCloned = true
   112  				clone()
   113  				schema.Dependencies = make(spec.Dependencies, len(orig.Dependencies))
   114  				for k2, v2 := range orig.Dependencies {
   115  					schema.Dependencies[k2] = v2
   116  				}
   117  			}
   118  			v.Schema = s
   119  			schema.Dependencies[k] = v
   120  		}
   121  	}
   122  
   123  	allOfCloned := false
   124  	for i := range schema.AllOf {
   125  		if s := PruneDefaultsSchema(&schema.AllOf[i]); s != &schema.AllOf[i] {
   126  			if !allOfCloned {
   127  				allOfCloned = true
   128  				clone()
   129  				schema.AllOf = make([]spec.Schema, len(orig.AllOf))
   130  				copy(schema.AllOf, orig.AllOf)
   131  			}
   132  			schema.AllOf[i] = *s
   133  		}
   134  	}
   135  
   136  	anyOfCloned := false
   137  	for i := range schema.AnyOf {
   138  		if s := PruneDefaultsSchema(&schema.AnyOf[i]); s != &schema.AnyOf[i] {
   139  			if !anyOfCloned {
   140  				anyOfCloned = true
   141  				clone()
   142  				schema.AnyOf = make([]spec.Schema, len(orig.AnyOf))
   143  				copy(schema.AnyOf, orig.AnyOf)
   144  			}
   145  			schema.AnyOf[i] = *s
   146  		}
   147  	}
   148  
   149  	oneOfCloned := false
   150  	for i := range schema.OneOf {
   151  		if s := PruneDefaultsSchema(&schema.OneOf[i]); s != &schema.OneOf[i] {
   152  			if !oneOfCloned {
   153  				oneOfCloned = true
   154  				clone()
   155  				schema.OneOf = make([]spec.Schema, len(orig.OneOf))
   156  				copy(schema.OneOf, orig.OneOf)
   157  			}
   158  			schema.OneOf[i] = *s
   159  		}
   160  	}
   161  
   162  	if schema.Not != nil {
   163  		if s := PruneDefaultsSchema(schema.Not); s != schema.Not {
   164  			clone()
   165  			schema.Not = s
   166  		}
   167  	}
   168  
   169  	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
   170  		if s := PruneDefaultsSchema(schema.AdditionalProperties.Schema); s != schema.AdditionalProperties.Schema {
   171  			clone()
   172  			schema.AdditionalProperties = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalProperties.Allows}
   173  		}
   174  	}
   175  
   176  	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
   177  		if s := PruneDefaultsSchema(schema.AdditionalItems.Schema); s != schema.AdditionalItems.Schema {
   178  			clone()
   179  			schema.AdditionalItems = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalItems.Allows}
   180  		}
   181  	}
   182  
   183  	if schema.Items != nil {
   184  		if schema.Items.Schema != nil {
   185  			if s := PruneDefaultsSchema(schema.Items.Schema); s != schema.Items.Schema {
   186  				clone()
   187  				schema.Items = &spec.SchemaOrArray{Schema: s}
   188  			}
   189  		} else {
   190  			itemsCloned := false
   191  			for i := range schema.Items.Schemas {
   192  				if s := PruneDefaultsSchema(&schema.Items.Schemas[i]); s != &schema.Items.Schemas[i] {
   193  					if !itemsCloned {
   194  						clone()
   195  						schema.Items = &spec.SchemaOrArray{
   196  							Schemas: make([]spec.Schema, len(orig.Items.Schemas)),
   197  						}
   198  						itemsCloned = true
   199  						copy(schema.Items.Schemas, orig.Items.Schemas)
   200  					}
   201  					schema.Items.Schemas[i] = *s
   202  				}
   203  			}
   204  		}
   205  	}
   206  
   207  	return schema
   208  }