github.com/alex123012/deckhouse-controller-tools@v0.0.0-20230510090815-d594daf1af8c/pkg/crd/known_types.go (about)

     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  package crd
    17  
    18  import (
    19  	apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    20  
    21  	"sigs.k8s.io/controller-tools/pkg/loader"
    22  )
    23  
    24  // KnownPackages overrides types in some comment packages that have custom validation
    25  // but don't have validation markers on them (since they're from core Kubernetes).
    26  var KnownPackages = map[string]PackageOverride{
    27  	"k8s.io/api/core/v1": func(p *Parser, pkg *loader.Package) {
    28  		// Explicit defaulting for the corev1.Protocol type in lieu of https://github.com/kubernetes/enhancements/pull/1928
    29  		p.Schemata[TypeIdent{Name: "Protocol", Package: pkg}] = apiext.JSONSchemaProps{
    30  			Type:    "string",
    31  			Default: &apiext.JSON{Raw: []byte(`"TCP"`)},
    32  		}
    33  		p.AddPackage(pkg)
    34  	},
    35  
    36  	"k8s.io/apimachinery/pkg/apis/meta/v1": func(p *Parser, pkg *loader.Package) {
    37  		p.Schemata[TypeIdent{Name: "ObjectMeta", Package: pkg}] = apiext.JSONSchemaProps{
    38  			Type: "object",
    39  		}
    40  		p.Schemata[TypeIdent{Name: "Time", Package: pkg}] = apiext.JSONSchemaProps{
    41  			Type:   "string",
    42  			Format: "date-time",
    43  		}
    44  		p.Schemata[TypeIdent{Name: "MicroTime", Package: pkg}] = apiext.JSONSchemaProps{
    45  			Type:   "string",
    46  			Format: "date-time",
    47  		}
    48  		p.Schemata[TypeIdent{Name: "Duration", Package: pkg}] = apiext.JSONSchemaProps{
    49  			// TODO(directxman12): regexp validation for this (or get kube to support it as a format value)
    50  			Type: "string",
    51  		}
    52  		p.Schemata[TypeIdent{Name: "Fields", Package: pkg}] = apiext.JSONSchemaProps{
    53  			// this is a recursive structure that can't be flattened or, for that matter, properly generated.
    54  			// so just treat it as an arbitrary map
    55  			Type:                 "object",
    56  			AdditionalProperties: &apiext.JSONSchemaPropsOrBool{Allows: true},
    57  		}
    58  		p.AddPackage(pkg) // get the rest of the types
    59  	},
    60  
    61  	"k8s.io/apimachinery/pkg/api/resource": func(p *Parser, pkg *loader.Package) {
    62  		p.Schemata[TypeIdent{Name: "Quantity", Package: pkg}] = apiext.JSONSchemaProps{
    63  			// TODO(directxman12): regexp validation for this (or get kube to support it as a format value)
    64  			XIntOrString: true,
    65  			AnyOf: []apiext.JSONSchemaProps{
    66  				{Type: "integer"},
    67  				{Type: "string"},
    68  			},
    69  			Pattern: "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
    70  		}
    71  		// No point in calling AddPackage, this is the sole inhabitant
    72  	},
    73  
    74  	"k8s.io/apimachinery/pkg/runtime": func(p *Parser, pkg *loader.Package) {
    75  		p.Schemata[TypeIdent{Name: "RawExtension", Package: pkg}] = apiext.JSONSchemaProps{
    76  			// TODO(directxman12): regexp validation for this (or get kube to support it as a format value)
    77  			Type:                   "object",
    78  			XPreserveUnknownFields: boolPtr(true),
    79  		}
    80  		p.AddPackage(pkg) // get the rest of the types
    81  	},
    82  
    83  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured": func(p *Parser, pkg *loader.Package) {
    84  		p.Schemata[TypeIdent{Name: "Unstructured", Package: pkg}] = apiext.JSONSchemaProps{
    85  			Type: "object",
    86  		}
    87  		p.AddPackage(pkg) // get the rest of the types
    88  	},
    89  
    90  	"k8s.io/apimachinery/pkg/util/intstr": func(p *Parser, pkg *loader.Package) {
    91  		p.Schemata[TypeIdent{Name: "IntOrString", Package: pkg}] = apiext.JSONSchemaProps{
    92  			XIntOrString: true,
    93  			AnyOf: []apiext.JSONSchemaProps{
    94  				{Type: "integer"},
    95  				{Type: "string"},
    96  			},
    97  		}
    98  		// No point in calling AddPackage, this is the sole inhabitant
    99  	},
   100  
   101  	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1": func(p *Parser, pkg *loader.Package) {
   102  		p.Schemata[TypeIdent{Name: "JSON", Package: pkg}] = apiext.JSONSchemaProps{
   103  			XPreserveUnknownFields: boolPtr(true),
   104  		}
   105  		p.AddPackage(pkg) // get the rest of the types
   106  	},
   107  	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1": func(p *Parser, pkg *loader.Package) {
   108  		p.Schemata[TypeIdent{Name: "JSON", Package: pkg}] = apiext.JSONSchemaProps{
   109  			XPreserveUnknownFields: boolPtr(true),
   110  		}
   111  		p.AddPackage(pkg) // get the rest of the types
   112  	},
   113  }
   114  
   115  // ObjectMetaPackages overrides the ObjectMeta in all types
   116  var ObjectMetaPackages = map[string]PackageOverride{
   117  	"k8s.io/apimachinery/pkg/apis/meta/v1": func(p *Parser, pkg *loader.Package) {
   118  		// execute the KnowPackages for `k8s.io/apimachinery/pkg/apis/meta/v1` if any
   119  		if f, ok := KnownPackages["k8s.io/apimachinery/pkg/apis/meta/v1"]; ok {
   120  			f(p, pkg)
   121  		}
   122  		// This is an allow-listed set of properties of ObjectMeta, other runtime properties are not part of this list
   123  		// See more discussion: https://github.com/kubernetes-sigs/controller-tools/pull/395#issuecomment-691919433
   124  		p.Schemata[TypeIdent{Name: "ObjectMeta", Package: pkg}] = apiext.JSONSchemaProps{
   125  			Type: "object",
   126  			Properties: map[string]apiext.JSONSchemaProps{
   127  				"name": {
   128  					Type: "string",
   129  				},
   130  				"namespace": {
   131  					Type: "string",
   132  				},
   133  				"annotations": {
   134  					Type: "object",
   135  					AdditionalProperties: &apiext.JSONSchemaPropsOrBool{
   136  						Schema: &apiext.JSONSchemaProps{
   137  							Type: "string",
   138  						},
   139  					},
   140  				},
   141  				"labels": {
   142  					Type: "object",
   143  					AdditionalProperties: &apiext.JSONSchemaPropsOrBool{
   144  						Schema: &apiext.JSONSchemaProps{
   145  							Type: "string",
   146  						},
   147  					},
   148  				},
   149  				"finalizers": {
   150  					Type: "array",
   151  					Items: &apiext.JSONSchemaPropsOrArray{
   152  						Schema: &apiext.JSONSchemaProps{
   153  							Type: "string",
   154  						},
   155  					},
   156  				},
   157  			},
   158  		}
   159  	},
   160  }
   161  
   162  func boolPtr(b bool) *bool {
   163  	return &b
   164  }
   165  
   166  // AddKnownTypes registers the packages overrides in KnownPackages with the given parser.
   167  func AddKnownTypes(parser *Parser) {
   168  	// ensure everything is there before adding to PackageOverrides
   169  	// TODO(directxman12): this is a bit of a hack, maybe just use constructors?
   170  	parser.init()
   171  	for pkgName, override := range KnownPackages {
   172  		parser.PackageOverrides[pkgName] = override
   173  	}
   174  	// if we want to generate the embedded ObjectMeta in the CRD we need to add the ObjectMetaPackages
   175  	if parser.GenerateEmbeddedObjectMeta {
   176  		for pkgName, override := range ObjectMetaPackages {
   177  			parser.PackageOverrides[pkgName] = override
   178  		}
   179  	}
   180  }