update dependencies (#6267)
Signed-off-by: hongming <coder.scala@gmail.com>
This commit is contained in:
2
vendor/sigs.k8s.io/controller-tools/pkg/crd/flatten.go
generated
vendored
2
vendor/sigs.k8s.io/controller-tools/pkg/crd/flatten.go
generated
vendored
@@ -147,6 +147,8 @@ func flattenAllOfInto(dst *apiext.JSONSchemaProps, src apiext.JSONSchemaProps, e
|
||||
dstField.Set(srcField)
|
||||
case "XMapType":
|
||||
dstField.Set(srcField)
|
||||
case "XValidations":
|
||||
dstField.Set(reflect.AppendSlice(srcField, dstField))
|
||||
// NB(directxman12): no need to explicitly handle nullable -- false is considered to be the zero value
|
||||
// TODO(directxman12): src isn't necessarily the field value -- it's just the most recent allOf entry
|
||||
default:
|
||||
|
||||
41
vendor/sigs.k8s.io/controller-tools/pkg/crd/gen.go
generated
vendored
41
vendor/sigs.k8s.io/controller-tools/pkg/crd/gen.go
generated
vendored
@@ -85,6 +85,20 @@ type Generator struct {
|
||||
|
||||
// Year specifies the year to substitute for " YEAR" in the header file.
|
||||
Year string `marker:",optional"`
|
||||
|
||||
// DeprecatedV1beta1CompatibilityPreserveUnknownFields indicates whether
|
||||
// or not we should turn off field pruning for this resource.
|
||||
//
|
||||
// Specifies spec.preserveUnknownFields value that is false and omitted by default.
|
||||
// This value can only be specified for CustomResourceDefinitions that were created with
|
||||
// `apiextensions.k8s.io/v1beta1`.
|
||||
//
|
||||
// The field can be set for compatiblity reasons, although strongly discouraged, resource
|
||||
// authors should move to a structural OpenAPI schema instead.
|
||||
//
|
||||
// See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning
|
||||
// for more information about field pruning and v1beta1 resources compatibility.
|
||||
DeprecatedV1beta1CompatibilityPreserveUnknownFields *bool `marker:",optional"`
|
||||
}
|
||||
|
||||
func (Generator) CheckFilter() loader.NodeFilter {
|
||||
@@ -100,15 +114,25 @@ func transformRemoveCRDStatus(obj map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// transformPreserveUnknownFields adds spec.preserveUnknownFields=value.
|
||||
func transformPreserveUnknownFields(value bool) func(map[string]interface{}) error {
|
||||
return func(obj map[string]interface{}) error {
|
||||
if spec, ok := obj["spec"].(map[interface{}]interface{}); ok {
|
||||
spec["preserveUnknownFields"] = value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
parser := &Parser{
|
||||
Collector: ctx.Collector,
|
||||
Checker: ctx.Checker,
|
||||
// Perform defaulting here to avoid ambiguity later
|
||||
IgnoreUnexportedFields: g.IgnoreUnexportedFields != nil && *g.IgnoreUnexportedFields == true,
|
||||
AllowDangerousTypes: g.AllowDangerousTypes != nil && *g.AllowDangerousTypes == true,
|
||||
IgnoreUnexportedFields: g.IgnoreUnexportedFields != nil && *g.IgnoreUnexportedFields,
|
||||
AllowDangerousTypes: g.AllowDangerousTypes != nil && *g.AllowDangerousTypes,
|
||||
// Indicates the parser on whether to register the ObjectMeta type or not
|
||||
GenerateEmbeddedObjectMeta: g.GenerateEmbeddedObjectMeta != nil && *g.GenerateEmbeddedObjectMeta == true,
|
||||
GenerateEmbeddedObjectMeta: g.GenerateEmbeddedObjectMeta != nil && *g.GenerateEmbeddedObjectMeta,
|
||||
}
|
||||
|
||||
AddKnownTypes(parser)
|
||||
@@ -146,6 +170,14 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
}
|
||||
headerText = strings.ReplaceAll(headerText, " YEAR", " "+g.Year)
|
||||
|
||||
yamlOpts := []*genall.WriteYAMLOptions{
|
||||
genall.WithTransform(transformRemoveCRDStatus),
|
||||
genall.WithTransform(genall.TransformRemoveCreationTimestamp),
|
||||
}
|
||||
if g.DeprecatedV1beta1CompatibilityPreserveUnknownFields != nil {
|
||||
yamlOpts = append(yamlOpts, genall.WithTransform(transformPreserveUnknownFields(*g.DeprecatedV1beta1CompatibilityPreserveUnknownFields)))
|
||||
}
|
||||
|
||||
for _, groupKind := range kubeKinds {
|
||||
parser.NeedCRDFor(groupKind, g.MaxDescLen)
|
||||
crdRaw := parser.CustomResourceDefinitions[groupKind]
|
||||
@@ -171,7 +203,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
} else {
|
||||
fileName = fmt.Sprintf("%s_%s.%s.yaml", crdRaw.Spec.Group, crdRaw.Spec.Names.Plural, crdVersions[i])
|
||||
}
|
||||
if err := ctx.WriteYAML(fileName, headerText, []interface{}{crd}, genall.WithTransform(transformRemoveCRDStatus), genall.WithTransform(genall.TransformRemoveCreationTimestamp)); err != nil {
|
||||
if err := ctx.WriteYAML(fileName, headerText, []interface{}{crd}, yamlOpts...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -194,7 +226,6 @@ func removeDescriptionFromMetadataProps(v *apiext.JSONSchemaProps) {
|
||||
if meta.Description != "" {
|
||||
meta.Description = ""
|
||||
v.Properties["metadata"] = m
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
vendor/sigs.k8s.io/controller-tools/pkg/crd/known_types.go
generated
vendored
20
vendor/sigs.k8s.io/controller-tools/pkg/crd/known_types.go
generated
vendored
@@ -17,6 +17,7 @@ package crd
|
||||
|
||||
import (
|
||||
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"sigs.k8s.io/controller-tools/pkg/loader"
|
||||
)
|
||||
@@ -24,15 +25,6 @@ import (
|
||||
// KnownPackages overrides types in some comment packages that have custom validation
|
||||
// but don't have validation markers on them (since they're from core Kubernetes).
|
||||
var KnownPackages = map[string]PackageOverride{
|
||||
"k8s.io/api/core/v1": func(p *Parser, pkg *loader.Package) {
|
||||
// Explicit defaulting for the corev1.Protocol type in lieu of https://github.com/kubernetes/enhancements/pull/1928
|
||||
p.Schemata[TypeIdent{Name: "Protocol", Package: pkg}] = apiext.JSONSchemaProps{
|
||||
Type: "string",
|
||||
Default: &apiext.JSON{Raw: []byte(`"TCP"`)},
|
||||
}
|
||||
p.AddPackage(pkg)
|
||||
},
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1": func(p *Parser, pkg *loader.Package) {
|
||||
p.Schemata[TypeIdent{Name: "ObjectMeta", Package: pkg}] = apiext.JSONSchemaProps{
|
||||
Type: "object",
|
||||
@@ -75,7 +67,7 @@ var KnownPackages = map[string]PackageOverride{
|
||||
p.Schemata[TypeIdent{Name: "RawExtension", Package: pkg}] = apiext.JSONSchemaProps{
|
||||
// TODO(directxman12): regexp validation for this (or get kube to support it as a format value)
|
||||
Type: "object",
|
||||
XPreserveUnknownFields: boolPtr(true),
|
||||
XPreserveUnknownFields: ptr.To(true),
|
||||
}
|
||||
p.AddPackage(pkg) // get the rest of the types
|
||||
},
|
||||
@@ -100,13 +92,13 @@ var KnownPackages = map[string]PackageOverride{
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1": func(p *Parser, pkg *loader.Package) {
|
||||
p.Schemata[TypeIdent{Name: "JSON", Package: pkg}] = apiext.JSONSchemaProps{
|
||||
XPreserveUnknownFields: boolPtr(true),
|
||||
XPreserveUnknownFields: ptr.To(true),
|
||||
}
|
||||
p.AddPackage(pkg) // get the rest of the types
|
||||
},
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1": func(p *Parser, pkg *loader.Package) {
|
||||
p.Schemata[TypeIdent{Name: "JSON", Package: pkg}] = apiext.JSONSchemaProps{
|
||||
XPreserveUnknownFields: boolPtr(true),
|
||||
XPreserveUnknownFields: ptr.To(true),
|
||||
}
|
||||
p.AddPackage(pkg) // get the rest of the types
|
||||
},
|
||||
@@ -159,10 +151,6 @@ var ObjectMetaPackages = map[string]PackageOverride{
|
||||
},
|
||||
}
|
||||
|
||||
func boolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// AddKnownTypes registers the packages overrides in KnownPackages with the given parser.
|
||||
func AddKnownTypes(parser *Parser) {
|
||||
// ensure everything is there before adding to PackageOverrides
|
||||
|
||||
32
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/crd.go
generated
vendored
32
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/crd.go
generated
vendored
@@ -55,6 +55,9 @@ var CRDMarkers = []*definitionWithHelp{
|
||||
|
||||
must(markers.MakeDefinition("kubebuilder:metadata", markers.DescribesType, Metadata{})).
|
||||
WithHelp(Metadata{}.Help()),
|
||||
|
||||
must(markers.MakeDefinition("kubebuilder:selectablefield", markers.DescribesType, SelectableField{})).
|
||||
WithHelp(SelectableField{}.Help()),
|
||||
}
|
||||
|
||||
// TODO: categories and singular used to be annotations types
|
||||
@@ -388,3 +391,32 @@ func (s Metadata) ApplyToCRD(crd *apiext.CustomResourceDefinition, _ string) err
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// +controllertools:marker:generateHelp:category=CRD
|
||||
|
||||
// SelectableField adds a field that may be used with field selectors.
|
||||
type SelectableField struct {
|
||||
// JSONPath specifies the jsonpath expression which is used to produce a field selector value.
|
||||
JSONPath string `marker:"JSONPath"`
|
||||
}
|
||||
|
||||
func (s SelectableField) ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error {
|
||||
var selectableFields *[]apiext.SelectableField
|
||||
for i := range crd.Versions {
|
||||
ver := &crd.Versions[i]
|
||||
if ver.Name != version {
|
||||
continue
|
||||
}
|
||||
selectableFields = &ver.SelectableFields
|
||||
break
|
||||
}
|
||||
if selectableFields == nil {
|
||||
return fmt.Errorf("selectable field applied to version %q not in CRD", version)
|
||||
}
|
||||
|
||||
*selectableFields = append(*selectableFields, apiext.SelectableField{
|
||||
JSONPath: s.JSONPath,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
17
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/doc.go
generated
vendored
17
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/doc.go
generated
vendored
@@ -26,7 +26,20 @@ limitations under the License.
|
||||
// be run after the rest of a given schema node has been generated.
|
||||
// Markers that need to be run before any other markers can also
|
||||
// implement ApplyFirst, but this is discouraged and may change
|
||||
// in the future.
|
||||
// in the future. It is recommended to implement the ApplyPriority
|
||||
// interface in combination with ApplyPriorityDefault and
|
||||
// ApplyPriorityFirst constants. Following is an example of how to
|
||||
// implement such a marker:
|
||||
//
|
||||
// type MyCustomMarker string
|
||||
//
|
||||
// func (m MyCustomMarker) ApplyPriority() ApplyPriority {
|
||||
// return ApplyPriorityFirst
|
||||
// }
|
||||
//
|
||||
// func (m MyCustomMarker) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// All validation markers start with "+kubebuilder:validation", and
|
||||
// have the same name as their type name.
|
||||
@@ -34,7 +47,7 @@ limitations under the License.
|
||||
// # CRD Markers
|
||||
//
|
||||
// Markers that modify anything in the CRD itself *except* for the schema
|
||||
// implement ApplyToCRD (crd.CRDMarker). They are expected to detect whether
|
||||
// implement ApplyToCRD (crd.SpecMarker). They are expected to detect whether
|
||||
// they should apply themselves to a specific version in the CRD (as passed to
|
||||
// them), or to the root-level CRD for legacy cases. They are applied *after*
|
||||
// the rest of the CRD is computed.
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/package.go
generated
vendored
2
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/package.go
generated
vendored
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
func init() {
|
||||
AllDefinitions = append(AllDefinitions,
|
||||
must(markers.MakeDefinition("groupName", markers.DescribesPackage, "")).
|
||||
mustOptional(markers.MakeDefinition("groupName", markers.DescribesPackage, "")).
|
||||
WithHelp(markers.SimpleHelp("CRD", "specifies the API group name for this package.")),
|
||||
|
||||
must(markers.MakeDefinition("versionName", markers.DescribesPackage, "")).
|
||||
|
||||
37
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/priority.go
generated
vendored
Normal file
37
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/priority.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package markers
|
||||
|
||||
// ApplyPriority designates the order markers should be applied.
|
||||
// Lower priority indicates it should be applied first
|
||||
type ApplyPriority int64
|
||||
|
||||
const (
|
||||
// ApplyPriorityDefault is the default priority for markers
|
||||
// that don't implement ApplyPriorityMarker
|
||||
ApplyPriorityDefault ApplyPriority = 10
|
||||
|
||||
// ApplyPriorityFirst is the priority value assigned to markers
|
||||
// that implement the ApplyFirst() method
|
||||
ApplyPriorityFirst ApplyPriority = 1
|
||||
)
|
||||
|
||||
// ApplyPriorityMarker designates the order validation markers should be applied.
|
||||
// Lower priority indicates it should be applied first
|
||||
type ApplyPriorityMarker interface {
|
||||
ApplyPriority() ApplyPriority
|
||||
}
|
||||
24
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/register.go
generated
vendored
24
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/register.go
generated
vendored
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package markers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"sigs.k8s.io/controller-tools/pkg/markers"
|
||||
@@ -42,12 +43,33 @@ func (d *definitionWithHelp) Register(reg *markers.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *definitionWithHelp) clone() *definitionWithHelp {
|
||||
newDef, newHelp := *d.Definition, *d.Help
|
||||
return &definitionWithHelp{
|
||||
Definition: &newDef,
|
||||
Help: &newHelp,
|
||||
}
|
||||
}
|
||||
|
||||
func must(def *markers.Definition, err error) *definitionWithHelp {
|
||||
return &definitionWithHelp{
|
||||
Definition: markers.Must(def, err),
|
||||
}
|
||||
}
|
||||
|
||||
func mustOptional(def *markers.Definition, err error) *definitionWithHelp {
|
||||
def = markers.Must(def, err)
|
||||
if !def.AnonymousField() {
|
||||
def = markers.Must(def, fmt.Errorf("not an anonymous field: %v", def))
|
||||
}
|
||||
field := def.Fields[""]
|
||||
field.Optional = true
|
||||
def.Fields[""] = field
|
||||
return &definitionWithHelp{
|
||||
Definition: def,
|
||||
}
|
||||
}
|
||||
|
||||
// AllDefinitions contains all marker definitions for this package.
|
||||
var AllDefinitions []*definitionWithHelp
|
||||
|
||||
@@ -60,7 +82,7 @@ type hasHelp interface {
|
||||
func mustMakeAllWithPrefix(prefix string, target markers.TargetType, objs ...interface{}) []*definitionWithHelp {
|
||||
defs := make([]*definitionWithHelp, len(objs))
|
||||
for i, obj := range objs {
|
||||
name := prefix + ":" + reflect.TypeOf(obj).Name()
|
||||
name := prefix + reflect.TypeOf(obj).Name()
|
||||
def, err := markers.MakeDefinition(name, target, obj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
4
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/topology.go
generated
vendored
4
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/topology.go
generated
vendored
@@ -119,7 +119,9 @@ func (l ListType) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l ListType) ApplyFirst() {}
|
||||
func (l ListType) ApplyPriority() ApplyPriority {
|
||||
return ApplyPriorityDefault - 1
|
||||
}
|
||||
|
||||
func (l ListMapKey) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
if schema.Type != "array" {
|
||||
|
||||
123
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/validation.go
generated
vendored
123
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/validation.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
|
||||
@@ -27,7 +28,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SchemalessName = "kubebuilder:validation:Schemaless"
|
||||
validationPrefix = "kubebuilder:validation:"
|
||||
|
||||
SchemalessName = "kubebuilder:validation:Schemaless"
|
||||
ValidationItemsPrefix = validationPrefix + "items:"
|
||||
)
|
||||
|
||||
// ValidationMarkers lists all available markers that affect CRD schema generation,
|
||||
@@ -35,7 +39,9 @@ const (
|
||||
// All markers start with `+kubebuilder:validation:`, and continue with their type name.
|
||||
// A copy is produced of all markers that describes types as well, for making types
|
||||
// reusable and writing complex validations on slice items.
|
||||
var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.DescribesField,
|
||||
// At last a copy of all markers with the prefix `+kubebuilder:validation:items:` is
|
||||
// produced for marking slice fields and types.
|
||||
var ValidationMarkers = mustMakeAllWithPrefix(validationPrefix, markers.DescribesField,
|
||||
|
||||
// numeric markers
|
||||
|
||||
@@ -74,17 +80,21 @@ var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.
|
||||
// sense on a type, and thus aren't in ValidationMarkers).
|
||||
var FieldOnlyMarkers = []*definitionWithHelp{
|
||||
must(markers.MakeDefinition("kubebuilder:validation:Required", markers.DescribesField, struct{}{})).
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is required, if fields are optional by default.")),
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is required.")),
|
||||
must(markers.MakeDefinition("kubebuilder:validation:Optional", markers.DescribesField, struct{}{})).
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is optional, if fields are required by default.")),
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is optional.")),
|
||||
must(markers.MakeDefinition("required", markers.DescribesField, struct{}{})).
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is required.")),
|
||||
must(markers.MakeDefinition("optional", markers.DescribesField, struct{}{})).
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is optional, if fields are required by default.")),
|
||||
WithHelp(markers.SimpleHelp("CRD validation", "specifies that this field is optional.")),
|
||||
|
||||
must(markers.MakeDefinition("nullable", markers.DescribesField, Nullable{})).
|
||||
WithHelp(Nullable{}.Help()),
|
||||
|
||||
must(markers.MakeAnyTypeDefinition("kubebuilder:default", markers.DescribesField, Default{})).
|
||||
WithHelp(Default{}.Help()),
|
||||
must(markers.MakeDefinition("default", markers.DescribesField, KubernetesDefault{})).
|
||||
WithHelp(KubernetesDefault{}.Help()),
|
||||
|
||||
must(markers.MakeAnyTypeDefinition("kubebuilder:example", markers.DescribesField, Example{})).
|
||||
WithHelp(Example{}.Help()),
|
||||
@@ -110,14 +120,22 @@ func init() {
|
||||
AllDefinitions = append(AllDefinitions, ValidationMarkers...)
|
||||
|
||||
for _, def := range ValidationMarkers {
|
||||
newDef := *def.Definition
|
||||
// copy both parts so we don't change the definition
|
||||
typDef := definitionWithHelp{
|
||||
Definition: &newDef,
|
||||
Help: def.Help,
|
||||
}
|
||||
typDef := def.clone()
|
||||
typDef.Target = markers.DescribesType
|
||||
AllDefinitions = append(AllDefinitions, &typDef)
|
||||
AllDefinitions = append(AllDefinitions, typDef)
|
||||
|
||||
itemsName := ValidationItemsPrefix + strings.TrimPrefix(def.Name, validationPrefix)
|
||||
|
||||
itemsFieldDef := def.clone()
|
||||
itemsFieldDef.Name = itemsName
|
||||
itemsFieldDef.Help.Summary = "for array items " + itemsFieldDef.Help.Summary
|
||||
AllDefinitions = append(AllDefinitions, itemsFieldDef)
|
||||
|
||||
itemsTypDef := def.clone()
|
||||
itemsTypDef.Name = itemsName
|
||||
itemsTypDef.Help.Summary = "for array items " + itemsTypDef.Help.Summary
|
||||
itemsTypDef.Target = markers.DescribesType
|
||||
AllDefinitions = append(AllDefinitions, itemsTypDef)
|
||||
}
|
||||
|
||||
AllDefinitions = append(AllDefinitions, FieldOnlyMarkers...)
|
||||
@@ -225,6 +243,20 @@ type Default struct {
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// +controllertools:marker:generateHelp:category="CRD validation"
|
||||
// Default sets the default value for this field.
|
||||
//
|
||||
// A default value will be accepted as any value valid for the field.
|
||||
// Only JSON-formatted values are accepted. `ref(...)` values are ignored.
|
||||
// Formatting for common types include: boolean: `true`, string:
|
||||
// `"Cluster"`, numerical: `1.24`, array: `[1,2]`, object: `{"policy":
|
||||
// "delete"}`). Defaults should be defined in pruned form, and only best-effort
|
||||
// validation will be performed. Full validation of a default requires
|
||||
// submission of the containing CRD to an apiserver.
|
||||
type KubernetesDefault struct {
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// +controllertools:marker:generateHelp:category="CRD validation"
|
||||
// Example sets the example value for this field.
|
||||
//
|
||||
@@ -266,7 +298,7 @@ type XEmbeddedResource struct{}
|
||||
// IntOrString marks a fields as an IntOrString.
|
||||
//
|
||||
// This is required when applying patterns or other validations to an IntOrString
|
||||
// field. Knwon information about the type is applied during the collapse phase
|
||||
// field. Known information about the type is applied during the collapse phase
|
||||
// and as such is not normally available during marker application.
|
||||
type XIntOrString struct{}
|
||||
|
||||
@@ -295,8 +327,11 @@ func isIntegral(value float64) bool {
|
||||
// This marker may be repeated to specify multiple expressions, all of
|
||||
// which must evaluate to true.
|
||||
type XValidation struct {
|
||||
Rule string
|
||||
Message string `marker:",optional"`
|
||||
Rule string
|
||||
Message string `marker:",optional"`
|
||||
MessageExpression string `marker:"messageExpression,optional"`
|
||||
Reason string `marker:"reason,optional"`
|
||||
FieldPath string `marker:"fieldPath,optional"`
|
||||
}
|
||||
|
||||
func (m Maximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
@@ -464,7 +499,9 @@ func (m Type) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m Type) ApplyFirst() {}
|
||||
func (m Type) ApplyPriority() ApplyPriority {
|
||||
return ApplyPriorityDefault - 1
|
||||
}
|
||||
|
||||
func (m Nullable) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
schema.Nullable = true
|
||||
@@ -484,6 +521,39 @@ func (m Default) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m Default) ApplyPriority() ApplyPriority {
|
||||
// explicitly go after +default markers, so kubebuilder-specific defaults get applied last and stomp
|
||||
return 10
|
||||
}
|
||||
|
||||
func (m *KubernetesDefault) ParseMarker(_ string, _ string, restFields string) error {
|
||||
if strings.HasPrefix(strings.TrimSpace(restFields), "ref(") {
|
||||
// Skip +default=ref(...) values for now, since we don't have a good way to evaluate go constant values via AST.
|
||||
// See https://github.com/kubernetes-sigs/controller-tools/pull/938#issuecomment-2096790018
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal([]byte(restFields), &m.Value)
|
||||
}
|
||||
|
||||
// Defaults are only valid CRDs created with the v1 API
|
||||
func (m KubernetesDefault) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
if m.Value == nil {
|
||||
// only apply to the schema if we have a non-nil default value
|
||||
return nil
|
||||
}
|
||||
marshalledDefault, err := json.Marshal(m.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
schema.Default = &apiext.JSON{Raw: marshalledDefault}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m KubernetesDefault) ApplyPriority() ApplyPriority {
|
||||
// explicitly go before +kubebuilder:default markers, so kubebuilder-specific defaults get applied last and stomp
|
||||
return 9
|
||||
}
|
||||
|
||||
func (m Example) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
marshalledExample, err := json.Marshal(m.Value)
|
||||
if err != nil {
|
||||
@@ -512,12 +582,27 @@ func (m XIntOrString) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m XIntOrString) ApplyFirst() {}
|
||||
func (m XIntOrString) ApplyPriority() ApplyPriority {
|
||||
return ApplyPriorityDefault - 1
|
||||
}
|
||||
|
||||
func (m XValidation) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
|
||||
var reason *apiext.FieldValueErrorReason
|
||||
if m.Reason != "" {
|
||||
switch m.Reason {
|
||||
case string(apiext.FieldValueRequired), string(apiext.FieldValueInvalid), string(apiext.FieldValueForbidden), string(apiext.FieldValueDuplicate):
|
||||
reason = (*apiext.FieldValueErrorReason)(&m.Reason)
|
||||
default:
|
||||
return fmt.Errorf("invalid reason %s, valid values are %s, %s, %s and %s", m.Reason, apiext.FieldValueRequired, apiext.FieldValueInvalid, apiext.FieldValueForbidden, apiext.FieldValueDuplicate)
|
||||
}
|
||||
}
|
||||
|
||||
schema.XValidations = append(schema.XValidations, apiext.ValidationRule{
|
||||
Rule: m.Rule,
|
||||
Message: m.Message,
|
||||
Rule: m.Rule,
|
||||
Message: m.Message,
|
||||
MessageExpression: m.MessageExpression,
|
||||
Reason: reason,
|
||||
FieldPath: m.FieldPath,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
146
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/zz_generated.markerhelp.go
generated
vendored
146
vendor/sigs.k8s.io/controller-tools/pkg/crd/markers/zz_generated.markerhelp.go
generated
vendored
@@ -28,8 +28,8 @@ func (Default) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "sets the default value for this field. ",
|
||||
Details: "A default value will be accepted as any value valid for the field. Formatting for common types include: boolean: `true`, string: `Cluster`, numerical: `1.24`, array: `{1,2}`, object: `{policy: \"delete\"}`). Defaults should be defined in pruned form, and only best-effort validation will be performed. Full validation of a default requires submission of the containing CRD to an apiserver.",
|
||||
Summary: "sets the default value for this field.",
|
||||
Details: "A default value will be accepted as any value valid for the\nfield. Formatting for common types include: boolean: `true`, string:\n`Cluster`, numerical: `1.24`, array: `{1,2}`, object: `{policy:\n\"delete\"}`). Defaults should be defined in pruned form, and only best-effort\nvalidation will be performed. Full validation of a default requires\nsubmission of the containing CRD to an apiserver.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Value": {
|
||||
@@ -71,8 +71,8 @@ func (Example) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "sets the example value for this field. ",
|
||||
Details: "An example value will be accepted as any value valid for the field. Formatting for common types include: boolean: `true`, string: `Cluster`, numerical: `1.24`, array: `{1,2}`, object: `{policy: \"delete\"}`). Examples should be defined in pruned form, and only best-effort validation will be performed. Full validation of an example requires submission of the containing CRD to an apiserver.",
|
||||
Summary: "sets the example value for this field.",
|
||||
Details: "An example value will be accepted as any value valid for the\nfield. Formatting for common types include: boolean: `true`, string:\n`Cluster`, numerical: `1.24`, array: `{1,2}`, object: `{policy:\n\"delete\"}`). Examples should be defined in pruned form, and only best-effort\nvalidation will be performed. Full validation of an example requires\nsubmission of the containing CRD to an apiserver.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Value": {
|
||||
@@ -109,19 +109,35 @@ func (Format) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "specifies additional \"complex\" formatting for this field. ",
|
||||
Details: "For example, a date-time field would be marked as \"type: string\" and \"format: date-time\".",
|
||||
Summary: "specifies additional \"complex\" formatting for this field.",
|
||||
Details: "For example, a date-time field would be marked as \"type: string\" and\n\"format: date-time\".",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
}
|
||||
|
||||
func (KubernetesDefault) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "Default sets the default value for this field.",
|
||||
Details: "A default value will be accepted as any value valid for the field.\nOnly JSON-formatted values are accepted. `ref(...)` values are ignored.\nFormatting for common types include: boolean: `true`, string:\n`\"Cluster\"`, numerical: `1.24`, array: `[1,2]`, object: `{\"policy\":\n\"delete\"}`). Defaults should be defined in pruned form, and only best-effort\nvalidation will be performed. Full validation of a default requires\nsubmission of the containing CRD to an apiserver.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Value": {
|
||||
Summary: "",
|
||||
Details: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (ListMapKey) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD processing",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "specifies the keys to map listTypes. ",
|
||||
Details: "It indicates the index of a map list. They can be repeated if multiple keys must be used. It can only be used when ListType is set to map, and the keys should be scalar types.",
|
||||
Summary: "specifies the keys to map listTypes.",
|
||||
Details: "It indicates the index of a map list. They can be repeated if multiple keys\nmust be used. It can only be used when ListType is set to map, and the keys\nshould be scalar types.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -131,8 +147,8 @@ func (ListType) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD processing",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "specifies the type of data-structure that the list represents (map, set, atomic). ",
|
||||
Details: "Possible data-structure types of a list are: \n - \"map\": it needs to have a key field, which will be used to build an associative list. A typical example is a the pod container list, which is indexed by the container name. \n - \"set\": Fields need to be \"scalar\", and there can be only one occurrence of each. \n - \"atomic\": All the fields in the list are treated as a single value, are typically manipulated together by the same actor.",
|
||||
Summary: "specifies the type of data-structure that the list",
|
||||
Details: "represents (map, set, atomic).\n\nPossible data-structure types of a list are:\n\n - \"map\": it needs to have a key field, which will be used to build an\n associative list. A typical example is a the pod container list,\n which is indexed by the container name.\n\n - \"set\": Fields need to be \"scalar\", and there can be only one\n occurrence of each.\n\n - \"atomic\": All the fields in the list are treated as a single value,\n are typically manipulated together by the same actor.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -142,8 +158,8 @@ func (MapType) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD processing",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "specifies the level of atomicity of the map; i.e. whether each item in the map is independent of the others, or all fields are treated as a single unit. ",
|
||||
Details: "Possible values: \n - \"granular\": items in the map are independent of each other, and can be manipulated by different actors. This is the default behavior. \n - \"atomic\": all fields are treated as one unit. Any changes have to replace the entire map.",
|
||||
Summary: "specifies the level of atomicity of the map;",
|
||||
Details: "i.e. whether each item in the map is independent of the others,\nor all fields are treated as a single unit.\n\nPossible values:\n\n - \"granular\": items in the map are independent of each other,\n and can be manipulated by different actors.\n This is the default behavior.\n\n - \"atomic\": all fields are treated as one unit.\n Any changes have to replace the entire map.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -197,8 +213,8 @@ func (Metadata) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "configures the additional annotations or labels for this CRD. For example adding annotation \"api-approved.kubernetes.io\" for a CRD with Kubernetes groups, or annotation \"cert-manager.io/inject-ca-from-secret\" for a CRD that needs CA injection.",
|
||||
Details: "",
|
||||
Summary: "configures the additional annotations or labels for this CRD.",
|
||||
Details: "For example adding annotation \"api-approved.kubernetes.io\" for a CRD with Kubernetes groups,\nor annotation \"cert-manager.io/inject-ca-from-secret\" for a CRD that needs CA injection.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Annotations": {
|
||||
@@ -272,7 +288,7 @@ func (Nullable) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "marks this field as allowing the \"null\" value. ",
|
||||
Summary: "marks this field as allowing the \"null\" value.",
|
||||
Details: "This is often not necessary, but may be helpful with custom serialization.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
@@ -303,8 +319,8 @@ func (PrintColumn) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"Type": {
|
||||
Summary: "indicates the type of the column. ",
|
||||
Details: "It may be any OpenAPI data type listed at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types.",
|
||||
Summary: "indicates the type of the column.",
|
||||
Details: "It may be any OpenAPI data type listed at\nhttps://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types.",
|
||||
},
|
||||
"JSONPath": {
|
||||
Summary: "specifies the jsonpath expression used to extract the value of the column.",
|
||||
@@ -315,12 +331,12 @@ func (PrintColumn) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"Format": {
|
||||
Summary: "specifies the format of the column. ",
|
||||
Details: "It may be any OpenAPI data format corresponding to the type, listed at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types.",
|
||||
Summary: "specifies the format of the column.",
|
||||
Details: "It may be any OpenAPI data format corresponding to the type, listed at\nhttps://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types.",
|
||||
},
|
||||
"Priority": {
|
||||
Summary: "indicates how important it is that this column be displayed. ",
|
||||
Details: "Lower priority (*higher* numbered) columns will be hidden if the terminal width is too small.",
|
||||
Summary: "indicates how important it is that this column be displayed.",
|
||||
Details: "Lower priority (*higher* numbered) columns will be hidden if the terminal\nwidth is too small.",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -335,24 +351,24 @@ func (Resource) Help() *markers.DefinitionHelp {
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Path": {
|
||||
Summary: "specifies the plural \"resource\" for this CRD. ",
|
||||
Details: "It generally corresponds to a plural, lower-cased version of the Kind. See https://book.kubebuilder.io/cronjob-tutorial/gvks.html.",
|
||||
Summary: "specifies the plural \"resource\" for this CRD.",
|
||||
Details: "It generally corresponds to a plural, lower-cased version of the Kind.\nSee https://book.kubebuilder.io/cronjob-tutorial/gvks.html.",
|
||||
},
|
||||
"ShortName": {
|
||||
Summary: "specifies aliases for this CRD. ",
|
||||
Details: "Short names are often used when people have work with your resource over and over again. For instance, \"rs\" for \"replicaset\" or \"crd\" for customresourcedefinition.",
|
||||
Summary: "specifies aliases for this CRD.",
|
||||
Details: "Short names are often used when people have work with your resource\nover and over again. For instance, \"rs\" for \"replicaset\" or\n\"crd\" for customresourcedefinition.",
|
||||
},
|
||||
"Categories": {
|
||||
Summary: "specifies which group aliases this resource is part of. ",
|
||||
Details: "Group aliases are used to work with groups of resources at once. The most common one is \"all\" which covers about a third of the base resources in Kubernetes, and is generally used for \"user-facing\" resources.",
|
||||
Summary: "specifies which group aliases this resource is part of.",
|
||||
Details: "Group aliases are used to work with groups of resources at once.\nThe most common one is \"all\" which covers about a third of the base\nresources in Kubernetes, and is generally used for \"user-facing\" resources.",
|
||||
},
|
||||
"Singular": {
|
||||
Summary: "overrides the singular form of your resource. ",
|
||||
Summary: "overrides the singular form of your resource.",
|
||||
Details: "The singular form is otherwise defaulted off the plural (path).",
|
||||
},
|
||||
"Scope": {
|
||||
Summary: "overrides the scope of the CRD (Cluster vs Namespaced). ",
|
||||
Details: "Scope defaults to \"Namespaced\". Cluster-scoped (\"Cluster\") resources don't exist in namespaces.",
|
||||
Summary: "overrides the scope of the CRD (Cluster vs Namespaced).",
|
||||
Details: "Scope defaults to \"Namespaced\". Cluster-scoped (\"Cluster\") resources\ndon't exist in namespaces.",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -362,19 +378,35 @@ func (Schemaless) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "marks a field as being a schemaless object. ",
|
||||
Details: "Schemaless objects are not introspected, so you must provide any type and validation information yourself. One use for this tag is for embedding fields that hold JSONSchema typed objects. Because this field disables all type checking, it is recommended to be used only as a last resort.",
|
||||
Summary: "marks a field as being a schemaless object.",
|
||||
Details: "Schemaless objects are not introspected, so you must provide\nany type and validation information yourself. One use for this\ntag is for embedding fields that hold JSONSchema typed objects.\nBecause this field disables all type checking, it is recommended\nto be used only as a last resort.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
}
|
||||
|
||||
func (SelectableField) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "adds a field that may be used with field selectors.",
|
||||
Details: "",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"JSONPath": {
|
||||
Summary: "specifies the jsonpath expression which is used to produce a field selector value.",
|
||||
Details: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (SkipVersion) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "removes the particular version of the CRD from the CRDs spec. ",
|
||||
Details: "This is useful if you need to skip generating and listing version entries for 'internal' resource versions, which typically exist if using the Kubernetes upstream conversion-gen tool.",
|
||||
Summary: "removes the particular version of the CRD from the CRDs spec.",
|
||||
Details: "This is useful if you need to skip generating and listing version entries\nfor 'internal' resource versions, which typically exist if using the\nKubernetes upstream conversion-gen tool.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -384,8 +416,8 @@ func (StorageVersion) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "marks this version as the \"storage version\" for the CRD for conversion. ",
|
||||
Details: "When conversion is enabled for a CRD (i.e. it's not a trivial-versions/single-version CRD), one version is set as the \"storage version\" to be stored in etcd. Attempting to store any other version will result in conversion to the storage version via a conversion webhook.",
|
||||
Summary: "marks this version as the \"storage version\" for the CRD for conversion.",
|
||||
Details: "When conversion is enabled for a CRD (i.e. it's not a trivial-versions/single-version CRD),\none version is set as the \"storage version\" to be stored in etcd. Attempting to store any\nother version will result in conversion to the storage version via a conversion webhook.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -395,8 +427,8 @@ func (StructType) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD processing",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "specifies the level of atomicity of the struct; i.e. whether each field in the struct is independent of the others, or all fields are treated as a single unit. ",
|
||||
Details: "Possible values: \n - \"granular\": fields in the struct are independent of each other, and can be manipulated by different actors. This is the default behavior. \n - \"atomic\": all fields are treated as one unit. Any changes have to replace the entire struct.",
|
||||
Summary: "specifies the level of atomicity of the struct;",
|
||||
Details: "i.e. whether each field in the struct is independent of the others,\nor all fields are treated as a single unit.\n\nPossible values:\n\n - \"granular\": fields in the struct are independent of each other,\n and can be manipulated by different actors.\n This is the default behavior.\n\n - \"atomic\": all fields are treated as one unit.\n Any changes have to replace the entire struct.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -419,8 +451,8 @@ func (SubresourceScale) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"SelectorPath": {
|
||||
Summary: "specifies the jsonpath to the pod label selector field for the scale's status. ",
|
||||
Details: "The selector field must be the *string* form (serialized form) of a selector. Setting a pod label selector is necessary for your type to work with the HorizontalPodAutoscaler.",
|
||||
Summary: "specifies the jsonpath to the pod label selector field for the scale's status.",
|
||||
Details: "The selector field must be the *string* form (serialized form) of a selector.\nSetting a pod label selector is necessary for your type to work with the HorizontalPodAutoscaler.",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -441,8 +473,8 @@ func (Type) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "overrides the type for this field (which defaults to the equivalent of the Go type). ",
|
||||
Details: "This generally must be paired with custom serialization. For example, the metav1.Time field would be marked as \"type: string\" and \"format: date-time\".",
|
||||
Summary: "overrides the type for this field (which defaults to the equivalent of the Go type).",
|
||||
Details: "This generally must be paired with custom serialization. For example, the\nmetav1.Time field would be marked as \"type: string\" and \"format: date-time\".",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -463,7 +495,7 @@ func (UnservedVersion) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "does not serve this version. ",
|
||||
Summary: "does not serve this version.",
|
||||
Details: "This is useful if you need to drop support for a version in favor of a newer version.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
@@ -474,8 +506,8 @@ func (XEmbeddedResource) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "EmbeddedResource marks a fields as an embedded resource with apiVersion, kind and metadata fields. ",
|
||||
Details: "An embedded resource is a value that has apiVersion, kind and metadata fields. They are validated implicitly according to the semantics of the currently running apiserver. It is not necessary to add any additional schema for these field, yet it is possible. This can be combined with PreserveUnknownFields.",
|
||||
Summary: "EmbeddedResource marks a fields as an embedded resource with apiVersion, kind and metadata fields.",
|
||||
Details: "An embedded resource is a value that has apiVersion, kind and metadata fields.\nThey are validated implicitly according to the semantics of the currently\nrunning apiserver. It is not necessary to add any additional schema for these\nfield, yet it is possible. This can be combined with PreserveUnknownFields.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -485,8 +517,8 @@ func (XIntOrString) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "IntOrString marks a fields as an IntOrString. ",
|
||||
Details: "This is required when applying patterns or other validations to an IntOrString field. Knwon information about the type is applied during the collapse phase and as such is not normally available during marker application.",
|
||||
Summary: "IntOrString marks a fields as an IntOrString.",
|
||||
Details: "This is required when applying patterns or other validations to an IntOrString\nfield. Known information about the type is applied during the collapse phase\nand as such is not normally available during marker application.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -496,8 +528,8 @@ func (XPreserveUnknownFields) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD processing",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "PreserveUnknownFields stops the apiserver from pruning fields which are not specified. ",
|
||||
Details: "By default the apiserver drops unknown fields from the request payload during the decoding step. This marker stops the API server from doing so. It affects fields recursively, but switches back to normal pruning behaviour if nested properties or additionalProperties are specified in the schema. This can either be true or undefined. False is forbidden. \n NB: The kubebuilder:validation:XPreserveUnknownFields variant is deprecated in favor of the kubebuilder:pruning:PreserveUnknownFields variant. They function identically.",
|
||||
Summary: "PreserveUnknownFields stops the apiserver from pruning fields which are not specified.",
|
||||
Details: "By default the apiserver drops unknown fields from the request payload\nduring the decoding step. This marker stops the API server from doing so.\nIt affects fields recursively, but switches back to normal pruning behaviour\nif nested properties or additionalProperties are specified in the schema.\nThis can either be true or undefined. False\nis forbidden.\n\nNB: The kubebuilder:validation:XPreserveUnknownFields variant is deprecated\nin favor of the kubebuilder:pruning:PreserveUnknownFields variant. They function\nidentically.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -507,8 +539,8 @@ func (XValidation) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "CRD validation",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "marks a field as requiring a value for which a given expression evaluates to true. ",
|
||||
Details: "This marker may be repeated to specify multiple expressions, all of which must evaluate to true.",
|
||||
Summary: "marks a field as requiring a value for which a given",
|
||||
Details: "expression evaluates to true.\n\nThis marker may be repeated to specify multiple expressions, all of\nwhich must evaluate to true.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Rule": {
|
||||
@@ -519,6 +551,18 @@ func (XValidation) Help() *markers.DefinitionHelp {
|
||||
Summary: "",
|
||||
Details: "",
|
||||
},
|
||||
"MessageExpression": {
|
||||
Summary: "",
|
||||
Details: "",
|
||||
},
|
||||
"Reason": {
|
||||
Summary: "",
|
||||
Details: "",
|
||||
},
|
||||
"FieldPath": {
|
||||
Summary: "",
|
||||
Details: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
138
vendor/sigs.k8s.io/controller-tools/pkg/crd/schema.go
generated
vendored
138
vendor/sigs.k8s.io/controller-tools/pkg/crd/schema.go
generated
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
@@ -124,39 +125,73 @@ func infoToSchema(ctx *schemaContext) *apiext.JSONSchemaProps {
|
||||
return typeToSchema(ctx, ctx.info.RawSpec.Type)
|
||||
}
|
||||
|
||||
// applyMarkers applies schema markers to the given schema, respecting "apply first" markers.
|
||||
type schemaMarkerWithName struct {
|
||||
SchemaMarker SchemaMarker
|
||||
Name string
|
||||
}
|
||||
|
||||
// applyMarkers applies schema markers given their priority to the given schema
|
||||
func applyMarkers(ctx *schemaContext, markerSet markers.MarkerValues, props *apiext.JSONSchemaProps, node ast.Node) {
|
||||
// apply "apply first" markers first...
|
||||
for _, markerValues := range markerSet {
|
||||
markers := make([]schemaMarkerWithName, 0, len(markerSet))
|
||||
itemsMarkers := make([]schemaMarkerWithName, 0, len(markerSet))
|
||||
|
||||
for markerName, markerValues := range markerSet {
|
||||
for _, markerValue := range markerValues {
|
||||
if _, isApplyFirst := markerValue.(applyFirstMarker); !isApplyFirst {
|
||||
continue
|
||||
}
|
||||
|
||||
schemaMarker, isSchemaMarker := markerValue.(SchemaMarker)
|
||||
if !isSchemaMarker {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := schemaMarker.ApplyToSchema(props); err != nil {
|
||||
ctx.pkg.AddError(loader.ErrFromNode(err /* an okay guess */, node))
|
||||
if schemaMarker, isSchemaMarker := markerValue.(SchemaMarker); isSchemaMarker {
|
||||
if strings.HasPrefix(markerName, crdmarkers.ValidationItemsPrefix) {
|
||||
itemsMarkers = append(itemsMarkers, schemaMarkerWithName{
|
||||
SchemaMarker: schemaMarker,
|
||||
Name: markerName,
|
||||
})
|
||||
} else {
|
||||
markers = append(markers, schemaMarkerWithName{
|
||||
SchemaMarker: schemaMarker,
|
||||
Name: markerName,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ...then the rest of the markers
|
||||
for _, markerValues := range markerSet {
|
||||
for _, markerValue := range markerValues {
|
||||
if _, isApplyFirst := markerValue.(applyFirstMarker); isApplyFirst {
|
||||
// skip apply-first markers, which were already applied
|
||||
continue
|
||||
}
|
||||
cmpPriority := func(markers []schemaMarkerWithName, i, j int) bool {
|
||||
var iPriority, jPriority crdmarkers.ApplyPriority
|
||||
|
||||
schemaMarker, isSchemaMarker := markerValue.(SchemaMarker)
|
||||
if !isSchemaMarker {
|
||||
continue
|
||||
}
|
||||
if err := schemaMarker.ApplyToSchema(props); err != nil {
|
||||
switch m := markers[i].SchemaMarker.(type) {
|
||||
case crdmarkers.ApplyPriorityMarker:
|
||||
iPriority = m.ApplyPriority()
|
||||
case applyFirstMarker:
|
||||
iPriority = crdmarkers.ApplyPriorityFirst
|
||||
default:
|
||||
iPriority = crdmarkers.ApplyPriorityDefault
|
||||
}
|
||||
|
||||
switch m := markers[j].SchemaMarker.(type) {
|
||||
case crdmarkers.ApplyPriorityMarker:
|
||||
jPriority = m.ApplyPriority()
|
||||
case applyFirstMarker:
|
||||
jPriority = crdmarkers.ApplyPriorityFirst
|
||||
default:
|
||||
jPriority = crdmarkers.ApplyPriorityDefault
|
||||
}
|
||||
|
||||
return iPriority < jPriority
|
||||
}
|
||||
sort.Slice(markers, func(i, j int) bool { return cmpPriority(markers, i, j) })
|
||||
sort.Slice(itemsMarkers, func(i, j int) bool { return cmpPriority(itemsMarkers, i, j) })
|
||||
|
||||
for _, schemaMarker := range markers {
|
||||
if err := schemaMarker.SchemaMarker.ApplyToSchema(props); err != nil {
|
||||
ctx.pkg.AddError(loader.ErrFromNode(err /* an okay guess */, node))
|
||||
}
|
||||
}
|
||||
|
||||
for _, schemaMarker := range itemsMarkers {
|
||||
if props.Type != "array" || props.Items == nil || props.Items.Schema == nil {
|
||||
err := fmt.Errorf("must apply %s to an array value, found %s", schemaMarker.Name, props.Type)
|
||||
ctx.pkg.AddError(loader.ErrFromNode(err, node))
|
||||
} else {
|
||||
itemsSchema := props.Items.Schema
|
||||
if err := schemaMarker.SchemaMarker.ApplyToSchema(itemsSchema); err != nil {
|
||||
ctx.pkg.AddError(loader.ErrFromNode(err /* an okay guess */, node))
|
||||
}
|
||||
}
|
||||
@@ -216,11 +251,30 @@ func localNamedToSchema(ctx *schemaContext, ident *ast.Ident) *apiext.JSONSchema
|
||||
ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("unknown type %s", ident.Name), ident))
|
||||
return &apiext.JSONSchemaProps{}
|
||||
}
|
||||
// This reproduces the behavior we had pre gotypesalias=1 (needed if this
|
||||
// project is compiled with default settings and Go >= 1.23).
|
||||
if aliasInfo, isAlias := typeInfo.(*types.Alias); isAlias {
|
||||
typeInfo = aliasInfo.Underlying()
|
||||
}
|
||||
if basicInfo, isBasic := typeInfo.(*types.Basic); isBasic {
|
||||
typ, fmt, err := builtinToType(basicInfo, ctx.allowDangerousTypes)
|
||||
if err != nil {
|
||||
ctx.pkg.AddError(loader.ErrFromNode(err, ident))
|
||||
}
|
||||
// Check for type aliasing to a basic type for gotypesalias=0. See more
|
||||
// in documentation https://pkg.go.dev/go/types#Alias:
|
||||
// > For gotypesalias=1, alias declarations produce an Alias type.
|
||||
// > Otherwise, the alias information is only in the type name, which
|
||||
// > points directly to the actual (aliased) type.
|
||||
if basicInfo.Name() != ident.Name {
|
||||
ctx.requestSchema("", ident.Name)
|
||||
link := TypeRefLink("", ident.Name)
|
||||
return &apiext.JSONSchemaProps{
|
||||
Type: typ,
|
||||
Format: fmt,
|
||||
Ref: &link,
|
||||
}
|
||||
}
|
||||
return &apiext.JSONSchemaProps{
|
||||
Type: typ,
|
||||
Format: fmt,
|
||||
@@ -228,7 +282,7 @@ func localNamedToSchema(ctx *schemaContext, ident *ast.Ident) *apiext.JSONSchema
|
||||
}
|
||||
// NB(directxman12): if there are dot imports, this might be an external reference,
|
||||
// so use typechecking info to get the actual object
|
||||
typeNameInfo := typeInfo.(*types.Named).Obj()
|
||||
typeNameInfo := typeInfo.(interface{ Obj() *types.TypeName }).Obj()
|
||||
pkg := typeNameInfo.Pkg()
|
||||
pkgPath := loader.NonVendorPath(pkg.Path())
|
||||
if pkg == ctx.pkg.Types {
|
||||
@@ -248,7 +302,7 @@ func namedToSchema(ctx *schemaContext, named *ast.SelectorExpr) *apiext.JSONSche
|
||||
ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("unknown type %v.%s", named.X, named.Sel.Name), named))
|
||||
return &apiext.JSONSchemaProps{}
|
||||
}
|
||||
typeInfo := typeInfoRaw.(*types.Named)
|
||||
typeInfo := typeInfoRaw.(interface{ Obj() *types.TypeName })
|
||||
typeNameInfo := typeInfo.Obj()
|
||||
nonVendorPath := loader.NonVendorPath(typeNameInfo.Pkg().Path())
|
||||
ctx.requestSchema(nonVendorPath, typeNameInfo.Name())
|
||||
@@ -378,20 +432,28 @@ func structToSchema(ctx *schemaContext, structType *ast.StructType) *apiext.JSON
|
||||
defaultMode = "optional"
|
||||
}
|
||||
|
||||
switch defaultMode {
|
||||
switch {
|
||||
case field.Markers.Get("kubebuilder:validation:Optional") != nil:
|
||||
// explicity optional - kubebuilder
|
||||
case field.Markers.Get("kubebuilder:validation:Required") != nil:
|
||||
// explicitly required - kubebuilder
|
||||
props.Required = append(props.Required, fieldName)
|
||||
case field.Markers.Get("optional") != nil:
|
||||
// explicity optional - kubernetes
|
||||
case field.Markers.Get("required") != nil:
|
||||
// explicitly required - kubernetes
|
||||
props.Required = append(props.Required, fieldName)
|
||||
|
||||
// if this package isn't set to optional default...
|
||||
case "required":
|
||||
// ...everything that's not inline, omitempty, or explicitly optional is required
|
||||
if !inline && !omitEmpty && field.Markers.Get("kubebuilder:validation:Optional") == nil && field.Markers.Get("optional") == nil {
|
||||
case defaultMode == "required":
|
||||
// ...everything that's not inline / omitempty is required
|
||||
if !inline && !omitEmpty {
|
||||
props.Required = append(props.Required, fieldName)
|
||||
}
|
||||
|
||||
// if this package isn't set to required default...
|
||||
case "optional":
|
||||
// ...everything that isn't explicitly required is optional
|
||||
if field.Markers.Get("kubebuilder:validation:Required") != nil {
|
||||
props.Required = append(props.Required, fieldName)
|
||||
}
|
||||
case defaultMode == "optional":
|
||||
// implicitly optional
|
||||
}
|
||||
|
||||
var propSchema *apiext.JSONSchemaProps
|
||||
@@ -453,7 +515,7 @@ func builtinToType(basic *types.Basic, allowDangerousTypes bool) (typ string, fo
|
||||
// Open coded go/types representation of encoding/json.Marshaller
|
||||
var jsonMarshaler = types.NewInterfaceType([]*types.Func{
|
||||
types.NewFunc(token.NoPos, nil, "MarshalJSON",
|
||||
types.NewSignature(nil, nil,
|
||||
types.NewSignatureType(nil, nil, nil, nil,
|
||||
types.NewTuple(
|
||||
types.NewVar(token.NoPos, nil, "", types.NewSlice(types.Universe.Lookup("byte").Type())),
|
||||
types.NewVar(token.NoPos, nil, "", types.Universe.Lookup("error").Type())), false)),
|
||||
|
||||
18
vendor/sigs.k8s.io/controller-tools/pkg/crd/zz_generated.markerhelp.go
generated
vendored
18
vendor/sigs.k8s.io/controller-tools/pkg/crd/zz_generated.markerhelp.go
generated
vendored
@@ -33,20 +33,20 @@ func (Generator) Help() *markers.DefinitionHelp {
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"IgnoreUnexportedFields": {
|
||||
Summary: "indicates that we should skip unexported fields. ",
|
||||
Summary: "indicates that we should skip unexported fields.",
|
||||
Details: "Left unspecified, the default is false.",
|
||||
},
|
||||
"AllowDangerousTypes": {
|
||||
Summary: "allows types which are usually omitted from CRD generation because they are not recommended. ",
|
||||
Details: "Currently the following additional types are allowed when this is true: float32 float64 \n Left unspecified, the default is false",
|
||||
Summary: "allows types which are usually omitted from CRD generation",
|
||||
Details: "because they are not recommended.\n\nCurrently the following additional types are allowed when this is true:\nfloat32\nfloat64\n\nLeft unspecified, the default is false",
|
||||
},
|
||||
"MaxDescLen": {
|
||||
Summary: "specifies the maximum description length for fields in CRD's OpenAPI schema. ",
|
||||
Details: "0 indicates drop the description for all fields completely. n indicates limit the description to at most n characters and truncate the description to closest sentence boundary if it exceeds n characters.",
|
||||
Summary: "specifies the maximum description length for fields in CRD's OpenAPI schema.",
|
||||
Details: "0 indicates drop the description for all fields completely.\nn indicates limit the description to at most n characters and truncate the description to\nclosest sentence boundary if it exceeds n characters.",
|
||||
},
|
||||
"CRDVersions": {
|
||||
Summary: "specifies the target API versions of the CRD type itself to generate. Defaults to v1. ",
|
||||
Details: "Currently, the only supported value is v1. \n The first version listed will be assumed to be the \"default\" version and will not get a version suffix in the output filename. \n You'll need to use \"v1\" to get support for features like defaulting, along with an API server that supports it (Kubernetes 1.16+).",
|
||||
Summary: "specifies the target API versions of the CRD type itself to",
|
||||
Details: "generate. Defaults to v1.\n\nCurrently, the only supported value is v1.\n\nThe first version listed will be assumed to be the \"default\" version and\nwill not get a version suffix in the output filename.\n\nYou'll need to use \"v1\" to get support for features like defaulting,\nalong with an API server that supports it (Kubernetes 1.16+).",
|
||||
},
|
||||
"GenerateEmbeddedObjectMeta": {
|
||||
Summary: "specifies if any embedded ObjectMeta in the CRD should be generated",
|
||||
@@ -60,6 +60,10 @@ func (Generator) Help() *markers.DefinitionHelp {
|
||||
Summary: "specifies the year to substitute for \" YEAR\" in the header file.",
|
||||
Details: "",
|
||||
},
|
||||
"DeprecatedV1beta1CompatibilityPreserveUnknownFields": {
|
||||
Summary: "indicates whether",
|
||||
Details: "or not we should turn off field pruning for this resource.\n\nSpecifies spec.preserveUnknownFields value that is false and omitted by default.\nThis value can only be specified for CustomResourceDefinitions that were created with\n`apiextensions.k8s.io/v1beta1`.\n\nThe field can be set for compatiblity reasons, although strongly discouraged, resource\nauthors should move to a structural OpenAPI schema instead.\n\nSee https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning\nfor more information about field pruning and v1beta1 resources compatibility.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
1
vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/gen.go
generated
vendored
1
vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/gen.go
generated
vendored
@@ -191,7 +191,6 @@ import (
|
||||
if err != nil {
|
||||
pkg.AddError(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// generateForPackage generates DeepCopy and runtime.Object implementations for
|
||||
|
||||
4
vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/zz_generated.markerhelp.go
generated
vendored
4
vendor/sigs.k8s.io/controller-tools/pkg/deepcopy/zz_generated.markerhelp.go
generated
vendored
@@ -28,8 +28,8 @@ func (Generator) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "generates code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.",
|
||||
Details: "",
|
||||
Summary: "generates code containing DeepCopy, DeepCopyInto, and",
|
||||
Details: "DeepCopyObject method implementations.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"HeaderFile": {
|
||||
|
||||
1
vendor/sigs.k8s.io/controller-tools/pkg/genall/options.go
generated
vendored
1
vendor/sigs.k8s.io/controller-tools/pkg/genall/options.go
generated
vendored
@@ -74,7 +74,6 @@ func RegistryFromOptions(optionsRegistry *markers.Registry, options []string) (*
|
||||
// further modified. Not default generators are used if none are specified -- you can check
|
||||
// the output and rerun for that.
|
||||
func FromOptions(optionsRegistry *markers.Registry, options []string) (*Runtime, error) {
|
||||
|
||||
protoRt, err := protoFromOptions(optionsRegistry, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
12
vendor/sigs.k8s.io/controller-tools/pkg/genall/zz_generated.markerhelp.go
generated
vendored
12
vendor/sigs.k8s.io/controller-tools/pkg/genall/zz_generated.markerhelp.go
generated
vendored
@@ -28,7 +28,7 @@ func (InputPaths) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "represents paths and go-style path patterns to use as package roots. ",
|
||||
Summary: "represents paths and go-style path patterns to use as package roots.",
|
||||
Details: "Multiple paths can be specified using \"{path1, path2, path3}\".",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
@@ -39,8 +39,8 @@ func (OutputArtifacts) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "outputs artifacts to different locations, depending on whether they're package-associated or not. ",
|
||||
Details: "Non-package associated artifacts are output to the Config directory, while package-associated ones are output to their package's source files' directory, unless an alternate path is specified in Code.",
|
||||
Summary: "outputs artifacts to different locations, depending on",
|
||||
Details: "whether they're package-associated or not.\n\nNon-package associated artifacts\nare output to the Config directory, while package-associated ones are output\nto their package's source files' directory, unless an alternate path is\nspecified in Code.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Config": {
|
||||
@@ -59,8 +59,8 @@ func (OutputToDirectory) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "outputs each artifact to the given directory, regardless of if it's package-associated or not.",
|
||||
Details: "",
|
||||
Summary: "outputs each artifact to the given directory, regardless",
|
||||
Details: "of if it's package-associated or not.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func (outputToStdout) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "outputs everything to standard-out, with no separation. ",
|
||||
Summary: "outputs everything to standard-out, with no separation.",
|
||||
Details: "Generally useful for single-artifact outputs.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
|
||||
11
vendor/sigs.k8s.io/controller-tools/pkg/loader/loader.go
generated
vendored
11
vendor/sigs.k8s.io/controller-tools/pkg/loader/loader.go
generated
vendored
@@ -370,7 +370,7 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, err
|
||||
cfg: cfg,
|
||||
packages: make(map[*packages.Package]*Package),
|
||||
}
|
||||
l.cfg.Mode |= packages.LoadImports | packages.NeedTypesSizes
|
||||
l.cfg.Mode |= packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedTypesSizes
|
||||
if l.cfg.Fset == nil {
|
||||
l.cfg.Fset = token.NewFileSet()
|
||||
}
|
||||
@@ -393,7 +393,7 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, err
|
||||
// and try and prevent packages from showing up twice when nested module
|
||||
// support is enabled. there is not harm that comes from this per se, but
|
||||
// it makes testing easier when a known number of modules can be asserted
|
||||
uniquePkgIDs := sets.String{}
|
||||
uniquePkgIDs := sets.Set[string]{}
|
||||
|
||||
// loadPackages returns the Go packages for the provided roots
|
||||
//
|
||||
@@ -489,7 +489,6 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, err
|
||||
p string,
|
||||
d os.DirEntry,
|
||||
e error) error {
|
||||
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
@@ -518,7 +517,6 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, err
|
||||
|
||||
// get the absolute path of the root
|
||||
if !filepath.IsAbs(r) {
|
||||
|
||||
// if the initial value of cfg.Dir was non-empty then use it when
|
||||
// building the absolute path to this root. otherwise use the
|
||||
// filepath.Abs function to get the absolute path of the root based
|
||||
@@ -548,7 +546,6 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, err
|
||||
if err := filepath.WalkDir(
|
||||
d,
|
||||
addNestedGoModulesToRoots); err != nil {
|
||||
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -604,9 +601,9 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, err
|
||||
// references with those from the rootPkgs list. This ensures the
|
||||
// kubebuilder marker generation is handled correctly. For more info,
|
||||
// please see issue 680.
|
||||
func visitImports(rootPkgs []*Package, pkg *Package, seen sets.String) {
|
||||
func visitImports(rootPkgs []*Package, pkg *Package, seen sets.Set[string]) {
|
||||
if seen == nil {
|
||||
seen = sets.String{}
|
||||
seen = sets.Set[string]{}
|
||||
}
|
||||
for importedPkgID, importedPkg := range pkg.Imports() {
|
||||
for i := range rootPkgs {
|
||||
|
||||
3
vendor/sigs.k8s.io/controller-tools/pkg/loader/refs.go
generated
vendored
3
vendor/sigs.k8s.io/controller-tools/pkg/loader/refs.go
generated
vendored
@@ -18,7 +18,6 @@ package loader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go/ast"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -164,7 +163,7 @@ func allReferencedPackages(pkg *Package, filterNodes NodeFilter) []*Package {
|
||||
refsByFile[file] = refs
|
||||
}
|
||||
|
||||
EachType(pkg, func(file *ast.File, decl *ast.GenDecl, spec *ast.TypeSpec) {
|
||||
EachType(pkg, func(file *ast.File, _ *ast.GenDecl, spec *ast.TypeSpec) {
|
||||
refs := refsByFile[file]
|
||||
refs.collectReferences(spec.Type, filterNodes)
|
||||
})
|
||||
|
||||
1
vendor/sigs.k8s.io/controller-tools/pkg/markers/collect.go
generated
vendored
1
vendor/sigs.k8s.io/controller-tools/pkg/markers/collect.go
generated
vendored
@@ -388,7 +388,6 @@ func (v markerSubVisitor) Visit(node ast.Node) ast.Visitor {
|
||||
v.commentInd = lastCommentInd + 1
|
||||
|
||||
return resVisitor
|
||||
|
||||
}
|
||||
|
||||
// associatedCommentsFor returns the doc comment group (if relevant and present) and end-of-line comment
|
||||
|
||||
12
vendor/sigs.k8s.io/controller-tools/pkg/markers/parse.go
generated
vendored
12
vendor/sigs.k8s.io/controller-tools/pkg/markers/parse.go
generated
vendored
@@ -820,13 +820,23 @@ func parserScanner(raw string, err func(*sc.Scanner, string)) *sc.Scanner {
|
||||
return scanner
|
||||
}
|
||||
|
||||
type markerParser interface {
|
||||
ParseMarker(name string, anonymousName string, restFields string) error
|
||||
}
|
||||
|
||||
// Parse uses the type information in this Definition to parse the given
|
||||
// raw marker in the form `+a:b:c=arg,d=arg` into an output object of the
|
||||
// type specified in the definition.
|
||||
func (d *Definition) Parse(rawMarker string) (interface{}, error) {
|
||||
name, anonName, fields := splitMarker(rawMarker)
|
||||
|
||||
out := reflect.Indirect(reflect.New(d.Output))
|
||||
outPointer := reflect.New(d.Output)
|
||||
out := reflect.Indirect(outPointer)
|
||||
|
||||
if parser, ok := outPointer.Interface().(markerParser); ok {
|
||||
err := parser.ParseMarker(name, anonName, fields)
|
||||
return out.Interface(), err
|
||||
}
|
||||
|
||||
// if we're a not a struct or have no arguments, treat the full `a:b:c` as the name,
|
||||
// otherwise, treat `c` as a field name, and `a:b` as the marker name.
|
||||
|
||||
37
vendor/sigs.k8s.io/controller-tools/pkg/markers/zip.go
generated
vendored
37
vendor/sigs.k8s.io/controller-tools/pkg/markers/zip.go
generated
vendored
@@ -69,13 +69,15 @@ func extractDoc(node ast.Node, decl *ast.GenDecl) string {
|
||||
// split lines, and re-join together as a single
|
||||
// paragraph, respecting double-newlines as
|
||||
// paragraph markers.
|
||||
outLines := strings.Split(outGroup.Text(), "\n")
|
||||
if outLines[len(outLines)-1] == "" {
|
||||
lines := strings.Split(outGroup.Text(), "\n")
|
||||
if lines[len(lines)-1] == "" {
|
||||
// chop off the extraneous last part
|
||||
outLines = outLines[:len(outLines)-1]
|
||||
lines = lines[:len(lines)-1]
|
||||
}
|
||||
|
||||
for i, line := range outLines {
|
||||
var outLines []string
|
||||
var insideCodeBlock bool
|
||||
for i, line := range lines {
|
||||
if isAsteriskComment {
|
||||
// Trim any extranous whitespace,
|
||||
// for handling /*…*/-style comments,
|
||||
@@ -86,10 +88,33 @@ func extractDoc(node ast.Node, decl *ast.GenDecl) string {
|
||||
// Respect that double-newline means
|
||||
// actual newline:
|
||||
if line == "" {
|
||||
outLines[i] = "\n"
|
||||
lines[i] = "\n"
|
||||
} else {
|
||||
outLines[i] = line
|
||||
lines[i] = line
|
||||
}
|
||||
|
||||
// Recognize markdown code blocks (``` or ~~~)
|
||||
// https://spec.commonmark.org/0.27/#fenced-code-blocks
|
||||
if strings.HasPrefix(line, "```") || strings.HasPrefix(line, "~~~") {
|
||||
insideCodeBlock = !insideCodeBlock
|
||||
}
|
||||
|
||||
if !insideCodeBlock {
|
||||
// If we are not inside markdown code block, follow the Kubernetes formatting conventions:
|
||||
// - Lines after --- are comments and should be ignored.
|
||||
// - Lines starting with TODO are comments and should be ignored.
|
||||
// See function fmtRawDoc() in https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/swagger_doc_generator.go
|
||||
|
||||
if strings.HasPrefix(line, "TODO") {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "---") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
outLines = append(outLines, line)
|
||||
}
|
||||
return strings.Join(outLines, "\n")
|
||||
}
|
||||
|
||||
128
vendor/sigs.k8s.io/controller-tools/pkg/rbac/parser.go
generated
vendored
128
vendor/sigs.k8s.io/controller-tools/pkg/rbac/parser.go
generated
vendored
@@ -93,6 +93,24 @@ func (r *Rule) key() ruleKey {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Rule) keyWithGroupResourceNamesURLsVerbs() string {
|
||||
key := r.key()
|
||||
verbs := strings.Join(r.Verbs, "&")
|
||||
return fmt.Sprintf("%s + %s + %s + %s", key.Groups, key.ResourceNames, key.URLs, verbs)
|
||||
}
|
||||
|
||||
func (r *Rule) keyWithResourcesResourceNamesURLsVerbs() string {
|
||||
key := r.key()
|
||||
verbs := strings.Join(r.Verbs, "&")
|
||||
return fmt.Sprintf("%s + %s + %s + %s", key.Resources, key.ResourceNames, key.URLs, verbs)
|
||||
}
|
||||
|
||||
func (r *Rule) keyWitGroupResourcesResourceNamesVerbs() string {
|
||||
key := r.key()
|
||||
verbs := strings.Join(r.Verbs, "&")
|
||||
return fmt.Sprintf("%s + %s + %s + %s", key.Groups, key.Resources, key.ResourceNames, verbs)
|
||||
}
|
||||
|
||||
// addVerbs adds new verbs into a Rule.
|
||||
// The duplicates in `r.Verbs` will be removed, and then `r.Verbs` will be sorted.
|
||||
func (r *Rule) addVerbs(verbs []string) {
|
||||
@@ -128,12 +146,6 @@ func removeDupAndSort(strs []string) []string {
|
||||
|
||||
// ToRule converts this rule to its Kubernetes API form.
|
||||
func (r *Rule) ToRule() rbacv1.PolicyRule {
|
||||
// fix the group names first, since letting people type "core" is nice
|
||||
for i, group := range r.Groups {
|
||||
if group == "core" {
|
||||
r.Groups[i] = ""
|
||||
}
|
||||
}
|
||||
return rbacv1.PolicyRule{
|
||||
APIGroups: r.Groups,
|
||||
Verbs: r.Verbs,
|
||||
@@ -168,22 +180,42 @@ func (Generator) RegisterMarkers(into *markers.Registry) error {
|
||||
// GenerateRoles generate a slice of objs representing either a ClusterRole or a Role object
|
||||
// The order of the objs in the returned slice is stable and determined by their namespaces.
|
||||
func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{}, error) {
|
||||
rulesByNS := make(map[string][]*Rule)
|
||||
rulesByNSResource := make(map[string][]*Rule)
|
||||
for _, root := range ctx.Roots {
|
||||
markerSet, err := markers.PackageMarkers(ctx.Collector, root)
|
||||
if err != nil {
|
||||
root.AddError(err)
|
||||
}
|
||||
|
||||
// group RBAC markers by namespace
|
||||
// group RBAC markers by namespace and separate by resource
|
||||
for _, markerValue := range markerSet[RuleDefinition.Name] {
|
||||
rule := markerValue.(Rule)
|
||||
namespace := rule.Namespace
|
||||
if _, ok := rulesByNS[namespace]; !ok {
|
||||
rules := make([]*Rule, 0)
|
||||
rulesByNS[namespace] = rules
|
||||
if len(rule.Resources) == 0 {
|
||||
// Add a rule without any resource if Resources is empty.
|
||||
r := Rule{
|
||||
Groups: rule.Groups,
|
||||
Resources: []string{},
|
||||
ResourceNames: rule.ResourceNames,
|
||||
URLs: rule.URLs,
|
||||
Namespace: rule.Namespace,
|
||||
Verbs: rule.Verbs,
|
||||
}
|
||||
namespace := r.Namespace
|
||||
rulesByNSResource[namespace] = append(rulesByNSResource[namespace], &r)
|
||||
continue
|
||||
}
|
||||
for _, resource := range rule.Resources {
|
||||
r := Rule{
|
||||
Groups: rule.Groups,
|
||||
Resources: []string{resource},
|
||||
ResourceNames: rule.ResourceNames,
|
||||
URLs: rule.URLs,
|
||||
Namespace: rule.Namespace,
|
||||
Verbs: rule.Verbs,
|
||||
}
|
||||
namespace := r.Namespace
|
||||
rulesByNSResource[namespace] = append(rulesByNSResource[namespace], &r)
|
||||
}
|
||||
rulesByNS[namespace] = append(rulesByNS[namespace], &rule)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,6 +224,13 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
|
||||
ruleMap := make(map[ruleKey]*Rule)
|
||||
// all the Rules having the same ruleKey will be merged into the first Rule
|
||||
for _, rule := range rules {
|
||||
// fix the group name first, since letting people type "core" is nice
|
||||
for i, name := range rule.Groups {
|
||||
if name == "core" {
|
||||
rule.Groups[i] = ""
|
||||
}
|
||||
}
|
||||
|
||||
key := rule.key()
|
||||
if _, ok := ruleMap[key]; !ok {
|
||||
ruleMap[key] = rule
|
||||
@@ -200,6 +239,64 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
|
||||
ruleMap[key].addVerbs(rule.Verbs)
|
||||
}
|
||||
|
||||
// deduplicate resources
|
||||
// 1. create map based on key without resources
|
||||
ruleMapWithoutResources := make(map[string][]*Rule)
|
||||
for _, rule := range ruleMap {
|
||||
// get key without Resources
|
||||
key := rule.keyWithGroupResourceNamesURLsVerbs()
|
||||
ruleMapWithoutResources[key] = append(ruleMapWithoutResources[key], rule)
|
||||
}
|
||||
// 2. merge to ruleMap
|
||||
ruleMap = make(map[ruleKey]*Rule)
|
||||
for _, rules := range ruleMapWithoutResources {
|
||||
rule := rules[0]
|
||||
for _, mergeRule := range rules[1:] {
|
||||
rule.Resources = append(rule.Resources, mergeRule.Resources...)
|
||||
}
|
||||
|
||||
key := rule.key()
|
||||
ruleMap[key] = rule
|
||||
}
|
||||
|
||||
// deduplicate groups
|
||||
// 1. create map based on key without group
|
||||
ruleMapWithoutGroup := make(map[string][]*Rule)
|
||||
for _, rule := range ruleMap {
|
||||
// get key without Group
|
||||
key := rule.keyWithResourcesResourceNamesURLsVerbs()
|
||||
ruleMapWithoutGroup[key] = append(ruleMapWithoutGroup[key], rule)
|
||||
}
|
||||
// 2. merge to ruleMap
|
||||
ruleMap = make(map[ruleKey]*Rule)
|
||||
for _, rules := range ruleMapWithoutGroup {
|
||||
rule := rules[0]
|
||||
for _, mergeRule := range rules[1:] {
|
||||
rule.Groups = append(rule.Groups, mergeRule.Groups...)
|
||||
}
|
||||
key := rule.key()
|
||||
ruleMap[key] = rule
|
||||
}
|
||||
|
||||
// deduplicate URLs
|
||||
// 1. create map based on key without URLs
|
||||
ruleMapWithoutURLs := make(map[string][]*Rule)
|
||||
for _, rule := range ruleMap {
|
||||
// get key without Group
|
||||
key := rule.keyWitGroupResourcesResourceNamesVerbs()
|
||||
ruleMapWithoutURLs[key] = append(ruleMapWithoutURLs[key], rule)
|
||||
}
|
||||
// 2. merge to ruleMap
|
||||
ruleMap = make(map[ruleKey]*Rule)
|
||||
for _, rules := range ruleMapWithoutURLs {
|
||||
rule := rules[0]
|
||||
for _, mergeRule := range rules[1:] {
|
||||
rule.URLs = append(rule.URLs, mergeRule.URLs...)
|
||||
}
|
||||
key := rule.key()
|
||||
ruleMap[key] = rule
|
||||
}
|
||||
|
||||
// sort the Rules in rules according to their ruleKeys
|
||||
keys := make([]ruleKey, 0, len(ruleMap))
|
||||
for key := range ruleMap {
|
||||
@@ -210,14 +307,13 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
|
||||
var policyRules []rbacv1.PolicyRule
|
||||
for _, key := range keys {
|
||||
policyRules = append(policyRules, ruleMap[key].ToRule())
|
||||
|
||||
}
|
||||
return policyRules
|
||||
}
|
||||
|
||||
// collect all the namespaces and sort them
|
||||
var namespaces []string
|
||||
for ns := range rulesByNS {
|
||||
for ns := range rulesByNSResource {
|
||||
namespaces = append(namespaces, ns)
|
||||
}
|
||||
sort.Strings(namespaces)
|
||||
@@ -225,7 +321,7 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
|
||||
// process the items in rulesByNS by the order specified in `namespaces` to make sure that the Role order is stable
|
||||
var objs []interface{}
|
||||
for _, ns := range namespaces {
|
||||
rules := rulesByNS[ns]
|
||||
rules := rulesByNSResource[ns]
|
||||
policyRules := NormalizeRules(rules)
|
||||
if len(policyRules) == 0 {
|
||||
continue
|
||||
|
||||
8
vendor/sigs.k8s.io/controller-tools/pkg/rbac/zz_generated.markerhelp.go
generated
vendored
8
vendor/sigs.k8s.io/controller-tools/pkg/rbac/zz_generated.markerhelp.go
generated
vendored
@@ -65,8 +65,8 @@ func (Rule) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"ResourceNames": {
|
||||
Summary: "specifies the names of the API resources that this rule encompasses. ",
|
||||
Details: "Create requests cannot be restricted by resourcename, as the object's name is not known at authorization time.",
|
||||
Summary: "specifies the names of the API resources that this rule encompasses.",
|
||||
Details: "Create requests cannot be restricted by resourcename, as the object's name\nis not known at authorization time.",
|
||||
},
|
||||
"Verbs": {
|
||||
Summary: "specifies the (lowercase) kubernetes API verbs that this rule encompasses.",
|
||||
@@ -77,8 +77,8 @@ func (Rule) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"Namespace": {
|
||||
Summary: "specifies the scope of the Rule. If not set, the Rule belongs to the generated ClusterRole. If set, the Rule belongs to a Role, whose namespace is specified by this field.",
|
||||
Details: "",
|
||||
Summary: "specifies the scope of the Rule.",
|
||||
Details: "If not set, the Rule belongs to the generated ClusterRole.\nIf set, the Rule belongs to a Role, whose namespace is specified by this field.",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/gen.go
generated
vendored
2
vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/gen.go
generated
vendored
@@ -92,7 +92,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) (result error) {
|
||||
Collector: ctx.Collector,
|
||||
Checker: ctx.Checker,
|
||||
// Indicates the parser on whether to register the ObjectMeta type or not
|
||||
GenerateEmbeddedObjectMeta: g.GenerateEmbeddedObjectMeta != nil && *g.GenerateEmbeddedObjectMeta == true,
|
||||
GenerateEmbeddedObjectMeta: g.GenerateEmbeddedObjectMeta != nil && *g.GenerateEmbeddedObjectMeta,
|
||||
}
|
||||
|
||||
crdgen.AddKnownTypes(parser)
|
||||
|
||||
8
vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/zz_generated.markerhelp.go
generated
vendored
8
vendor/sigs.k8s.io/controller-tools/pkg/schemapatcher/zz_generated.markerhelp.go
generated
vendored
@@ -28,8 +28,8 @@ func (Generator) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "patches existing CRDs with new schemata. ",
|
||||
Details: "It will generate output for each \"CRD Version\" (API version of the CRD type itself) , e.g. apiextensions/v1) available.",
|
||||
Summary: "patches existing CRDs with new schemata.",
|
||||
Details: "It will generate output for each \"CRD Version\" (API version of the CRD type\nitself) , e.g. apiextensions/v1) available.",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"ManifestsPath": {
|
||||
@@ -37,8 +37,8 @@ func (Generator) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"MaxDescLen": {
|
||||
Summary: "specifies the maximum description length for fields in CRD's OpenAPI schema. ",
|
||||
Details: "0 indicates drop the description for all fields completely. n indicates limit the description to at most n characters and truncate the description to closest sentence boundary if it exceeds n characters.",
|
||||
Summary: "specifies the maximum description length for fields in CRD's OpenAPI schema.",
|
||||
Details: "0 indicates drop the description for all fields completely.\nn indicates limit the description to at most n characters and truncate the description to\nclosest sentence boundary if it exceeds n characters.",
|
||||
},
|
||||
"GenerateEmbeddedObjectMeta": {
|
||||
Summary: "specifies if any embedded ObjectMeta in the CRD should be generated",
|
||||
|
||||
10
vendor/sigs.k8s.io/controller-tools/pkg/version/version.go
generated
vendored
10
vendor/sigs.k8s.io/controller-tools/pkg/version/version.go
generated
vendored
@@ -13,6 +13,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package version provides the version of the main module.
|
||||
package version
|
||||
|
||||
import (
|
||||
@@ -20,8 +22,16 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
// version to be set using ldflags:
|
||||
// -ldflags "-X sigs.k8s.io/controller-tools/pkg/version.version=v1.0.0"
|
||||
// falls back to module information is unset
|
||||
var version = ""
|
||||
|
||||
// Version returns the version of the main module
|
||||
func Version() string {
|
||||
if version != "" {
|
||||
return version
|
||||
}
|
||||
info, ok := debug.ReadBuildInfo()
|
||||
if !ok || info == nil || info.Main.Version == "" {
|
||||
// binary has not been built with module support or doesn't contain a version.
|
||||
|
||||
110
vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go
generated
vendored
110
vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go
generated
vendored
@@ -31,6 +31,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-tools/pkg/genall"
|
||||
"sigs.k8s.io/controller-tools/pkg/markers"
|
||||
)
|
||||
@@ -42,9 +43,11 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// ConfigDefinition s a marker for defining Webhook manifests.
|
||||
// ConfigDefinition is a marker for defining Webhook manifests.
|
||||
// Call ToWebhook on the value to get a Kubernetes Webhook.
|
||||
ConfigDefinition = markers.Must(markers.MakeDefinition("kubebuilder:webhook", markers.DescribesPackage, Config{}))
|
||||
// WebhookConfigDefinition is a marker for defining MutatingWebhookConfiguration or ValidatingWebhookConfiguration manifests.
|
||||
WebhookConfigDefinition = markers.Must(markers.MakeDefinition("kubebuilder:webhookconfiguration", markers.DescribesPackage, WebhookConfig{}))
|
||||
)
|
||||
|
||||
// supportedWebhookVersions returns currently supported API version of {Mutating,Validating}WebhookConfiguration.
|
||||
@@ -52,6 +55,19 @@ func supportedWebhookVersions() []string {
|
||||
return []string{defaultWebhookVersion}
|
||||
}
|
||||
|
||||
// +controllertools:marker:generateHelp
|
||||
|
||||
type WebhookConfig struct {
|
||||
// Mutating marks this as a mutating webhook (it's validating only if false)
|
||||
//
|
||||
// Mutating webhooks are allowed to change the object in their response,
|
||||
// and are called *before* all validating webhooks. Mutating webhooks may
|
||||
// choose to reject an object, similarly to a validating webhook.
|
||||
Mutating bool
|
||||
// Name indicates the name of the K8s MutatingWebhookConfiguration or ValidatingWebhookConfiguration object.
|
||||
Name string `marker:"name,optional"`
|
||||
}
|
||||
|
||||
// +controllertools:marker:generateHelp:category=Webhook
|
||||
|
||||
// Config specifies how a webhook should be served.
|
||||
@@ -154,6 +170,32 @@ func verbToAPIVariant(verbRaw string) admissionregv1.OperationType {
|
||||
}
|
||||
}
|
||||
|
||||
// ToMutatingWebhookConfiguration converts this WebhookConfig to its Kubernetes API form.
|
||||
func (c WebhookConfig) ToMutatingWebhookConfiguration() (admissionregv1.MutatingWebhookConfiguration, error) {
|
||||
if !c.Mutating {
|
||||
return admissionregv1.MutatingWebhookConfiguration{}, fmt.Errorf("%s is a validating webhook", c.Name)
|
||||
}
|
||||
|
||||
return admissionregv1.MutatingWebhookConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: c.Name,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ToValidatingWebhookConfiguration converts this WebhookConfig to its Kubernetes API form.
|
||||
func (c WebhookConfig) ToValidatingWebhookConfiguration() (admissionregv1.ValidatingWebhookConfiguration, error) {
|
||||
if c.Mutating {
|
||||
return admissionregv1.ValidatingWebhookConfiguration{}, fmt.Errorf("%s is a mutating webhook", c.Name)
|
||||
}
|
||||
|
||||
return admissionregv1.ValidatingWebhookConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: c.Name,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ToMutatingWebhook converts this rule to its Kubernetes API form.
|
||||
func (c Config) ToMutatingWebhook() (admissionregv1.MutatingWebhook, error) {
|
||||
if !c.Mutating {
|
||||
@@ -289,7 +331,6 @@ func (c Config) clientConfig() (admissionregv1.WebhookClientConfig, error) {
|
||||
return admissionregv1.WebhookClientConfig{
|
||||
URL: &url,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
// sideEffects returns the sideEffects config for a webhook.
|
||||
@@ -363,7 +404,11 @@ func (Generator) RegisterMarkers(into *markers.Registry) error {
|
||||
if err := into.Register(ConfigDefinition); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := into.Register(WebhookConfigDefinition); err != nil {
|
||||
return err
|
||||
}
|
||||
into.AddHelp(ConfigDefinition, Config{}.Help())
|
||||
into.AddHelp(WebhookConfigDefinition, Config{}.Help())
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -371,12 +416,43 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
supportedWebhookVersions := supportedWebhookVersions()
|
||||
mutatingCfgs := make(map[string][]admissionregv1.MutatingWebhook, len(supportedWebhookVersions))
|
||||
validatingCfgs := make(map[string][]admissionregv1.ValidatingWebhook, len(supportedWebhookVersions))
|
||||
var mutatingWebhookCfgs admissionregv1.MutatingWebhookConfiguration
|
||||
var validatingWebhookCfgs admissionregv1.ValidatingWebhookConfiguration
|
||||
|
||||
for _, root := range ctx.Roots {
|
||||
markerSet, err := markers.PackageMarkers(ctx.Collector, root)
|
||||
if err != nil {
|
||||
root.AddError(err)
|
||||
}
|
||||
|
||||
webhookCfgs := markerSet[WebhookConfigDefinition.Name]
|
||||
var hasValidatingWebhookConfig, hasMutatingWebhookConfig bool = false, false
|
||||
for _, webhookCfg := range webhookCfgs {
|
||||
webhookCfg := webhookCfg.(WebhookConfig)
|
||||
|
||||
if webhookCfg.Mutating {
|
||||
if hasMutatingWebhookConfig {
|
||||
return fmt.Errorf("duplicate mutating %s with name %s", WebhookConfigDefinition.Name, webhookCfg.Name)
|
||||
}
|
||||
|
||||
if mutatingWebhookCfgs, err = webhookCfg.ToMutatingWebhookConfiguration(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hasMutatingWebhookConfig = true
|
||||
} else {
|
||||
if hasValidatingWebhookConfig {
|
||||
return fmt.Errorf("duplicate validating %s with name %s", WebhookConfigDefinition.Name, webhookCfg.Name)
|
||||
}
|
||||
|
||||
if validatingWebhookCfgs, err = webhookCfg.ToValidatingWebhookConfiguration(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hasValidatingWebhookConfig = true
|
||||
}
|
||||
}
|
||||
|
||||
cfgs := markerSet[ConfigDefinition.Name]
|
||||
sort.SliceStable(cfgs, func(i, j int) bool {
|
||||
return cfgs[i].(Config).Name < cfgs[j].(Config).Name
|
||||
@@ -411,16 +487,22 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
versionedWebhooks := make(map[string][]interface{}, len(supportedWebhookVersions))
|
||||
for _, version := range supportedWebhookVersions {
|
||||
if cfgs, ok := mutatingCfgs[version]; ok {
|
||||
// The only possible version in supportedWebhookVersions is v1,
|
||||
// so use it for all versioned types in this context.
|
||||
objRaw := &admissionregv1.MutatingWebhookConfiguration{}
|
||||
var objRaw *admissionregv1.MutatingWebhookConfiguration
|
||||
if mutatingWebhookCfgs.Name != "" {
|
||||
objRaw = &mutatingWebhookCfgs
|
||||
} else {
|
||||
// The only possible version in supportedWebhookVersions is v1,
|
||||
// so use it for all versioned types in this context.
|
||||
objRaw = &admissionregv1.MutatingWebhookConfiguration{}
|
||||
objRaw.SetName("mutating-webhook-configuration")
|
||||
}
|
||||
objRaw.SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: admissionregv1.SchemeGroupVersion.Group,
|
||||
Version: version,
|
||||
Kind: "MutatingWebhookConfiguration",
|
||||
})
|
||||
objRaw.SetName("mutating-webhook-configuration")
|
||||
objRaw.Webhooks = cfgs
|
||||
|
||||
for i := range objRaw.Webhooks {
|
||||
// SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`,
|
||||
// return an error
|
||||
@@ -442,16 +524,22 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
}
|
||||
|
||||
if cfgs, ok := validatingCfgs[version]; ok {
|
||||
// The only possible version in supportedWebhookVersions is v1,
|
||||
// so use it for all versioned types in this context.
|
||||
objRaw := &admissionregv1.ValidatingWebhookConfiguration{}
|
||||
var objRaw *admissionregv1.ValidatingWebhookConfiguration
|
||||
if validatingWebhookCfgs.Name != "" {
|
||||
objRaw = &validatingWebhookCfgs
|
||||
} else {
|
||||
// The only possible version in supportedWebhookVersions is v1,
|
||||
// so use it for all versioned types in this context.
|
||||
objRaw = &admissionregv1.ValidatingWebhookConfiguration{}
|
||||
objRaw.SetName("validating-webhook-configuration")
|
||||
}
|
||||
objRaw.SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: admissionregv1.SchemeGroupVersion.Group,
|
||||
Version: version,
|
||||
Kind: "ValidatingWebhookConfiguration",
|
||||
})
|
||||
objRaw.SetName("validating-webhook-configuration")
|
||||
objRaw.Webhooks = cfgs
|
||||
|
||||
for i := range objRaw.Webhooks {
|
||||
// SideEffects is required in admissionregistration/v1, if this is not set or set to `Some` or `Known`,
|
||||
// return an error
|
||||
@@ -486,7 +574,7 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
for k, v := range versionedWebhooks {
|
||||
var fileName string
|
||||
if k == defaultWebhookVersion {
|
||||
fileName = fmt.Sprintf("manifests.yaml")
|
||||
fileName = "manifests.yaml"
|
||||
} else {
|
||||
fileName = fmt.Sprintf("manifests.%s.yaml", k)
|
||||
}
|
||||
|
||||
68
vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go
generated
vendored
68
vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go
generated
vendored
@@ -28,29 +28,29 @@ func (Config) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "Webhook",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "specifies how a webhook should be served. ",
|
||||
Details: "It specifies only the details that are intrinsic to the application serving it (e.g. the resources it can handle, or the path it serves on).",
|
||||
Summary: "specifies how a webhook should be served.",
|
||||
Details: "It specifies only the details that are intrinsic to the application serving\nit (e.g. the resources it can handle, or the path it serves on).",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Mutating": {
|
||||
Summary: "marks this as a mutating webhook (it's validating only if false) ",
|
||||
Details: "Mutating webhooks are allowed to change the object in their response, and are called *before* all validating webhooks. Mutating webhooks may choose to reject an object, similarly to a validating webhook.",
|
||||
Summary: "marks this as a mutating webhook (it's validating only if false)",
|
||||
Details: "Mutating webhooks are allowed to change the object in their response,\nand are called *before* all validating webhooks. Mutating webhooks may\nchoose to reject an object, similarly to a validating webhook.",
|
||||
},
|
||||
"FailurePolicy": {
|
||||
Summary: "specifies what should happen if the API server cannot reach the webhook. ",
|
||||
Details: "It may be either \"ignore\" (to skip the webhook and continue on) or \"fail\" (to reject the object in question).",
|
||||
Summary: "specifies what should happen if the API server cannot reach the webhook.",
|
||||
Details: "It may be either \"ignore\" (to skip the webhook and continue on) or \"fail\" (to reject\nthe object in question).",
|
||||
},
|
||||
"MatchPolicy": {
|
||||
Summary: "defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" (match only if it exactly matches the specified rule) or \"Equivalent\" (match a request if it modifies a resource listed in rules, even via another API group or version).",
|
||||
Details: "",
|
||||
Summary: "defines how the \"rules\" list is used to match incoming requests.",
|
||||
Details: "Allowed values are \"Exact\" (match only if it exactly matches the specified rule)\nor \"Equivalent\" (match a request if it modifies a resource listed in rules, even via another API group or version).",
|
||||
},
|
||||
"SideEffects": {
|
||||
Summary: "specify whether calling the webhook will have side effects. This has an impact on dry runs and `kubectl diff`: if the sideEffect is \"Unknown\" (the default) or \"Some\", then the API server will not call the webhook on a dry-run request and fails instead. If the value is \"None\", then the webhook has no side effects and the API server will call it on dry-run. If the value is \"NoneOnDryRun\", then the webhook is responsible for inspecting the \"dryRun\" property of the AdmissionReview sent in the request, and avoiding side effects if that value is \"true.\"",
|
||||
Details: "",
|
||||
Summary: "specify whether calling the webhook will have side effects.",
|
||||
Details: "This has an impact on dry runs and `kubectl diff`: if the sideEffect is \"Unknown\" (the default) or \"Some\", then\nthe API server will not call the webhook on a dry-run request and fails instead.\nIf the value is \"None\", then the webhook has no side effects and the API server will call it on dry-run.\nIf the value is \"NoneOnDryRun\", then the webhook is responsible for inspecting the \"dryRun\" property of the\nAdmissionReview sent in the request, and avoiding side effects if that value is \"true.\"",
|
||||
},
|
||||
"TimeoutSeconds": {
|
||||
Summary: "allows configuring how long the API server should wait for a webhook to respond before treating the call as a failure. If the timeout expires before the webhook responds, the webhook call will be ignored or the API call will be rejected based on the failure policy. The timeout value must be between 1 and 30 seconds. The timeout for an admission webhook defaults to 10 seconds.",
|
||||
Details: "",
|
||||
Summary: "allows configuring how long the API server should wait for a webhook to respond before treating the call as a failure.",
|
||||
Details: "If the timeout expires before the webhook responds, the webhook call will be ignored or the API call will be rejected based on the failure policy.\nThe timeout value must be between 1 and 30 seconds.\nThe timeout for an admission webhook defaults to 10 seconds.",
|
||||
},
|
||||
"Groups": {
|
||||
Summary: "specifies the API groups that this webhook receives requests for.",
|
||||
@@ -61,8 +61,8 @@ func (Config) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"Verbs": {
|
||||
Summary: "specifies the Kubernetes API verbs that this webhook receives requests for. ",
|
||||
Details: "Only modification-like verbs may be specified. May be \"create\", \"update\", \"delete\", \"connect\", or \"*\" (for all).",
|
||||
Summary: "specifies the Kubernetes API verbs that this webhook receives requests for.",
|
||||
Details: "Only modification-like verbs may be specified.\nMay be \"create\", \"update\", \"delete\", \"connect\", or \"*\" (for all).",
|
||||
},
|
||||
"Versions": {
|
||||
Summary: "specifies the API versions that this webhook receives requests for.",
|
||||
@@ -73,20 +73,24 @@ func (Config) Help() *markers.DefinitionHelp {
|
||||
Details: "",
|
||||
},
|
||||
"Path": {
|
||||
Summary: "specifies that path that the API server should connect to this webhook on. Must be prefixed with a '/validate-' or '/mutate-' depending on the type, and followed by $GROUP-$VERSION-$KIND where all values are lower-cased and the periods in the group are substituted for hyphens. For example, a validating webhook path for type batch.tutorial.kubebuilder.io/v1,Kind=CronJob would be /validate-batch-tutorial-kubebuilder-io-v1-cronjob",
|
||||
Details: "",
|
||||
Summary: "specifies that path that the API server should connect to this webhook on. Must be",
|
||||
Details: "prefixed with a '/validate-' or '/mutate-' depending on the type, and followed by\n$GROUP-$VERSION-$KIND where all values are lower-cased and the periods in the group\nare substituted for hyphens. For example, a validating webhook path for type\nbatch.tutorial.kubebuilder.io/v1,Kind=CronJob would be\n/validate-batch-tutorial-kubebuilder-io-v1-cronjob",
|
||||
},
|
||||
"WebhookVersions": {
|
||||
Summary: "specifies the target API versions of the {Mutating,Validating}WebhookConfiguration objects itself to generate. The only supported value is v1. Defaults to v1.",
|
||||
Details: "",
|
||||
Summary: "specifies the target API versions of the {Mutating,Validating}WebhookConfiguration objects",
|
||||
Details: "itself to generate. The only supported value is v1. Defaults to v1.",
|
||||
},
|
||||
"AdmissionReviewVersions": {
|
||||
Summary: "is an ordered list of preferred `AdmissionReview` versions the Webhook expects.",
|
||||
Details: "",
|
||||
Summary: "is an ordered list of preferred `AdmissionReview`",
|
||||
Details: "versions the Webhook expects.",
|
||||
},
|
||||
"ReinvocationPolicy": {
|
||||
Summary: "allows mutating webhooks to request reinvocation after other mutations ",
|
||||
Details: "To allow mutating admission plugins to observe changes made by other plugins, built-in mutating admission plugins are re-run if a mutating webhook modifies an object, and mutating webhooks can specify a reinvocationPolicy to control whether they are reinvoked as well.",
|
||||
Summary: "allows mutating webhooks to request reinvocation after other mutations",
|
||||
Details: "To allow mutating admission plugins to observe changes made by other plugins,\nbuilt-in mutating admission plugins are re-run if a mutating webhook modifies\nan object, and mutating webhooks can specify a reinvocationPolicy to control\nwhether they are reinvoked as well.",
|
||||
},
|
||||
"URL": {
|
||||
Summary: "allows mutating webhooks configuration to specify an external URL when generating",
|
||||
Details: "the manifests, instead of using the internal service communication. Should be in format of\nhttps://address:port/path\nWhen this option is specified, the serviceConfig.Service is removed from webhook the manifest.\nThe URL configuration should be between quotes.\n`url` cannot be specified when `path` is specified.",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -111,3 +115,23 @@ func (Generator) Help() *markers.DefinitionHelp {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (WebhookConfig) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "",
|
||||
Details: "",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Mutating": {
|
||||
Summary: "marks this as a mutating webhook (it's validating only if false)",
|
||||
Details: "Mutating webhooks are allowed to change the object in their response,\nand are called *before* all validating webhooks. Mutating webhooks may\nchoose to reject an object, similarly to a validating webhook.",
|
||||
},
|
||||
"Name": {
|
||||
Summary: "indicates the name of the K8s MutatingWebhookConfiguration or ValidatingWebhookConfiguration object.",
|
||||
Details: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user