use istio client-go library instead of knative (#1661)
use istio client-go library instead of knative bump kubernetes dependency version change code coverage to codecov
This commit is contained in:
89
vendor/sigs.k8s.io/controller-tools/pkg/webhook/admission.go
generated
vendored
89
vendor/sigs.k8s.io/controller-tools/pkg/webhook/admission.go
generated
vendored
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 webhook
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// admissionWebhook contains bits needed for generating a admissionWebhook Configuration
|
||||
type admissionWebhook struct {
|
||||
// name is the name of the webhook
|
||||
name string
|
||||
// typ is the webhook type, i.e. mutating, validating
|
||||
typ webhookType
|
||||
// path is the path this webhook will serve.
|
||||
path string
|
||||
// rules maps to the rules field in admissionregistrationv1beta1.admissionWebhook
|
||||
rules []admissionregistrationv1beta1.RuleWithOperations
|
||||
// failurePolicy maps to the failurePolicy field in admissionregistrationv1beta1.admissionWebhook
|
||||
// This optional. If not set, will be defaulted to Ignore (fail-open) by the server.
|
||||
// More details: https://github.com/kubernetes/api/blob/f5c295feaba2cbc946f0bbb8b535fc5f6a0345ee/admissionregistration/v1beta1/types.go#L144-L147
|
||||
failurePolicy *admissionregistrationv1beta1.FailurePolicyType
|
||||
// namespaceSelector maps to the namespaceSelector field in admissionregistrationv1beta1.admissionWebhook
|
||||
// This optional.
|
||||
namespaceSelector *metav1.LabelSelector
|
||||
}
|
||||
|
||||
func (w *admissionWebhook) setDefaults() {
|
||||
if len(w.path) == 0 {
|
||||
if len(w.rules) == 0 || len(w.rules[0].Resources) == 0 {
|
||||
// can't do defaulting, skip it.
|
||||
return
|
||||
}
|
||||
if w.typ == mutatingWebhook {
|
||||
w.path = "/mutate-" + w.rules[0].Resources[0]
|
||||
} else if w.typ == validatingWebhook {
|
||||
w.path = "/validate-" + w.rules[0].Resources[0]
|
||||
}
|
||||
}
|
||||
if len(w.name) == 0 {
|
||||
reg := regexp.MustCompile("[^a-zA-Z0-9]+")
|
||||
processedPath := strings.ToLower(reg.ReplaceAllString(w.path, ""))
|
||||
w.name = processedPath + ".example.com"
|
||||
}
|
||||
}
|
||||
|
||||
var _ webhook = &admissionWebhook{}
|
||||
|
||||
// GetType returns the type of the webhook.
|
||||
func (w *admissionWebhook) GetType() webhookType {
|
||||
return w.typ
|
||||
}
|
||||
|
||||
// Validate validates if the webhook is valid.
|
||||
func (w *admissionWebhook) Validate() error {
|
||||
if len(w.rules) == 0 {
|
||||
return errors.New("field rules should not be empty")
|
||||
}
|
||||
if len(w.name) == 0 {
|
||||
return errors.New("field name should not be empty")
|
||||
}
|
||||
if w.typ != mutatingWebhook && w.typ != validatingWebhook {
|
||||
return fmt.Errorf("unsupported Type: %v, only mutatingWebhook and validatingWebhook are supported", w.typ)
|
||||
}
|
||||
if len(w.path) == 0 {
|
||||
return errors.New("field path should not be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
334
vendor/sigs.k8s.io/controller-tools/pkg/webhook/generator.go
generated
vendored
334
vendor/sigs.k8s.io/controller-tools/pkg/webhook/generator.go
generated
vendored
@@ -1,334 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 webhook
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistration "k8s.io/api/admissionregistration/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
apitypes "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
type generatorOptions struct {
|
||||
// webhooks maps a path to a webhoook.
|
||||
webhooks map[string]webhook
|
||||
|
||||
// port is the port number that the server will serve.
|
||||
// It will be defaulted to 443 if unspecified.
|
||||
port int32
|
||||
|
||||
// certDir is the directory that contains the server key and certificate.
|
||||
certDir string
|
||||
|
||||
// mutatingWebhookConfigName is the name that used for creating the MutatingWebhookConfiguration object.
|
||||
mutatingWebhookConfigName string
|
||||
// validatingWebhookConfigName is the name that used for creating the ValidatingWebhookConfiguration object.
|
||||
validatingWebhookConfigName string
|
||||
|
||||
// secret is the location for storing the certificate for the admission server.
|
||||
// The server should have permission to create a secret in the namespace.
|
||||
secret *apitypes.NamespacedName
|
||||
|
||||
// service is a k8s service fronting the webhook server pod(s).
|
||||
// One and only one of service and host can be set.
|
||||
// This maps to field .Webhooks.ClientConfig.Service
|
||||
// https://github.com/kubernetes/api/blob/183f3326a9353bd6d41430fc80f96259331d029c/admissionregistration/v1beta1/types.go#L260
|
||||
service *service
|
||||
// host is the host name of .Webhooks.ClientConfig.URL
|
||||
// https://github.com/kubernetes/api/blob/183f3326a9353bd6d41430fc80f96259331d029c/admissionregistration/v1beta1/types.go#L250
|
||||
// One and only one of service and host can be set.
|
||||
// If neither service nor host is unspecified, host will be defaulted to "localhost".
|
||||
host *string
|
||||
}
|
||||
|
||||
// service contains information for creating a Service
|
||||
type service struct {
|
||||
// name of the Service
|
||||
name string
|
||||
// namespace of the Service
|
||||
namespace string
|
||||
// selectors is the selector of the Service.
|
||||
// This must select the pods that runs this webhook server.
|
||||
selectors map[string]string
|
||||
}
|
||||
|
||||
// setDefaults does defaulting for the generatorOptions.
|
||||
func (o *generatorOptions) setDefaults() {
|
||||
if o.webhooks == nil {
|
||||
o.webhooks = map[string]webhook{}
|
||||
}
|
||||
if o.port <= 0 {
|
||||
o.port = 443
|
||||
}
|
||||
if len(o.certDir) == 0 {
|
||||
o.certDir = path.Join("/tmp", "k8s-webhook-server", "serving-certs")
|
||||
}
|
||||
|
||||
if len(o.mutatingWebhookConfigName) == 0 {
|
||||
o.mutatingWebhookConfigName = "mutating-webhook-configuration"
|
||||
}
|
||||
if len(o.validatingWebhookConfigName) == 0 {
|
||||
o.validatingWebhookConfigName = "validating-webhook-configuration"
|
||||
}
|
||||
if o.host == nil && o.service == nil {
|
||||
varString := "localhost"
|
||||
o.host = &varString
|
||||
}
|
||||
}
|
||||
|
||||
// Generate creates the AdmissionWebhookConfiguration objects and Service if any.
|
||||
// It also provisions the certificate for the admission server.
|
||||
func (o *generatorOptions) Generate() ([]runtime.Object, error) {
|
||||
// do defaulting if necessary
|
||||
o.setDefaults()
|
||||
|
||||
webhookConfigurations, err := o.whConfigs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
svc := o.getService()
|
||||
objects := append(webhookConfigurations, svc)
|
||||
|
||||
return objects, nil
|
||||
}
|
||||
|
||||
// whConfigs creates a mutatingWebhookConfiguration and(or) a validatingWebhookConfiguration.
|
||||
func (o *generatorOptions) whConfigs() ([]runtime.Object, error) {
|
||||
for _, webhook := range o.webhooks {
|
||||
if err := webhook.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
objs := []runtime.Object{}
|
||||
mutatingWH, err := o.mutatingWHConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mutatingWH != nil {
|
||||
objs = append(objs, mutatingWH)
|
||||
}
|
||||
validatingWH, err := o.validatingWHConfigs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if validatingWH != nil {
|
||||
objs = append(objs, validatingWH)
|
||||
}
|
||||
return objs, nil
|
||||
}
|
||||
|
||||
// mutatingWHConfig creates mutatingWebhookConfiguration.
|
||||
func (o *generatorOptions) mutatingWHConfig() (runtime.Object, error) {
|
||||
mutatingWebhooks := []v1beta1.Webhook{}
|
||||
for path, webhook := range o.webhooks {
|
||||
if webhook.GetType() != mutatingWebhook {
|
||||
continue
|
||||
}
|
||||
|
||||
aw := webhook.(*admissionWebhook)
|
||||
wh, err := o.admissionWebhook(path, aw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutatingWebhooks = append(mutatingWebhooks, *wh)
|
||||
}
|
||||
|
||||
sort.Slice(mutatingWebhooks, func(i, j int) bool {
|
||||
return mutatingWebhooks[i].Name < mutatingWebhooks[j].Name
|
||||
})
|
||||
|
||||
if len(mutatingWebhooks) > 0 {
|
||||
return &admissionregistration.MutatingWebhookConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: metav1.GroupVersion{Group: admissionregistration.GroupName, Version: "v1beta1"}.String(),
|
||||
Kind: "MutatingWebhookConfiguration",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: o.mutatingWebhookConfigName,
|
||||
Annotations: map[string]string{
|
||||
// TODO(DirectXMan12): Change the annotation to the format that cert-manager decides to use.
|
||||
"alpha.admissionwebhook.cert-manager.io": "true",
|
||||
},
|
||||
},
|
||||
Webhooks: mutatingWebhooks,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (o *generatorOptions) validatingWHConfigs() (runtime.Object, error) {
|
||||
validatingWebhooks := []v1beta1.Webhook{}
|
||||
for path, webhook := range o.webhooks {
|
||||
var aw *admissionWebhook
|
||||
if webhook.GetType() != validatingWebhook {
|
||||
continue
|
||||
}
|
||||
|
||||
aw = webhook.(*admissionWebhook)
|
||||
wh, err := o.admissionWebhook(path, aw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validatingWebhooks = append(validatingWebhooks, *wh)
|
||||
}
|
||||
|
||||
sort.Slice(validatingWebhooks, func(i, j int) bool {
|
||||
return validatingWebhooks[i].Name < validatingWebhooks[j].Name
|
||||
})
|
||||
|
||||
if len(validatingWebhooks) > 0 {
|
||||
return &admissionregistration.ValidatingWebhookConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: metav1.GroupVersion{Group: admissionregistration.GroupName, Version: "v1beta1"}.String(),
|
||||
Kind: "ValidatingWebhookConfiguration",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: o.validatingWebhookConfigName,
|
||||
Annotations: map[string]string{
|
||||
// TODO(DirectXMan12): Change the annotation to the format that cert-manager decides to use.
|
||||
"alpha.admissionwebhook.cert-manager.io": "true",
|
||||
},
|
||||
},
|
||||
Webhooks: validatingWebhooks,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (o *generatorOptions) admissionWebhook(path string, wh *admissionWebhook) (*admissionregistration.Webhook, error) {
|
||||
if wh.namespaceSelector == nil && o.service != nil && len(o.service.namespace) > 0 {
|
||||
wh.namespaceSelector = &metav1.LabelSelector{
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
{
|
||||
Key: "control-plane",
|
||||
Operator: metav1.LabelSelectorOpDoesNotExist,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
webhook := &admissionregistration.Webhook{
|
||||
Name: wh.name,
|
||||
Rules: wh.rules,
|
||||
FailurePolicy: wh.failurePolicy,
|
||||
NamespaceSelector: wh.namespaceSelector,
|
||||
}
|
||||
cc, err := o.getClientConfigWithPath(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
webhook.ClientConfig = *cc
|
||||
return webhook, nil
|
||||
}
|
||||
|
||||
// getClientConfigWithPath constructs a WebhookClientConfig based on the server generatorOptions.
|
||||
// It will use path to the set the path in WebhookClientConfig.
|
||||
func (o *generatorOptions) getClientConfigWithPath(path string) (*admissionregistration.WebhookClientConfig, error) {
|
||||
cc, err := o.getClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cc, setPath(cc, path)
|
||||
}
|
||||
|
||||
func (o *generatorOptions) getClientConfig() (*admissionregistration.WebhookClientConfig, error) {
|
||||
if o.host != nil && o.service != nil {
|
||||
return nil, errors.New("URL and service can't be set at the same time")
|
||||
}
|
||||
cc := &admissionregistration.WebhookClientConfig{
|
||||
// Put an non-empty and not harmful CABundle here.
|
||||
// Not doing this will cause the field
|
||||
CABundle: []byte(`\n`),
|
||||
}
|
||||
if o.host != nil {
|
||||
u := url.URL{
|
||||
Scheme: "https",
|
||||
Host: net.JoinHostPort(*o.host, strconv.Itoa(int(o.port))),
|
||||
}
|
||||
urlString := u.String()
|
||||
cc.URL = &urlString
|
||||
}
|
||||
if o.service != nil {
|
||||
cc.Service = &admissionregistration.ServiceReference{
|
||||
Name: o.service.name,
|
||||
Namespace: o.service.namespace,
|
||||
// Path will be set later
|
||||
}
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
// setPath sets the path in the WebhookClientConfig.
|
||||
func setPath(cc *admissionregistration.WebhookClientConfig, path string) error {
|
||||
if cc.URL != nil {
|
||||
u, err := url.Parse(*cc.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Path = path
|
||||
urlString := u.String()
|
||||
cc.URL = &urlString
|
||||
}
|
||||
if cc.Service != nil {
|
||||
cc.Service.Path = &path
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getService creates a corev1.Service object fronting the admission server.
|
||||
func (o *generatorOptions) getService() runtime.Object {
|
||||
if o.service == nil {
|
||||
return nil
|
||||
}
|
||||
svc := &corev1.Service{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: o.service.name,
|
||||
Namespace: o.service.namespace,
|
||||
Annotations: map[string]string{
|
||||
// Secret here only need name, since it will be in the same namespace as the service.
|
||||
// TODO(DirectXMan12): Change the annotation to the format that cert-manager decides to use.
|
||||
"alpha.service.cert-manager.io/serving-cert-secret-name": o.secret.Name,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
Selector: o.service.selectors,
|
||||
Ports: []corev1.ServicePort{
|
||||
{
|
||||
// When using service, kube-apiserver will send admission request to port 443.
|
||||
Port: 443,
|
||||
TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: o.port},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return svc
|
||||
}
|
||||
151
vendor/sigs.k8s.io/controller-tools/pkg/webhook/manifests.go
generated
vendored
151
vendor/sigs.k8s.io/controller-tools/pkg/webhook/manifests.go
generated
vendored
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 webhook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"sigs.k8s.io/controller-tools/pkg/internal/general"
|
||||
)
|
||||
|
||||
// Options represent options for generating the webhook manifests.
|
||||
type Options struct {
|
||||
// WriterOptions specifies the input and output
|
||||
WriterOptions
|
||||
|
||||
generatorOptions
|
||||
}
|
||||
|
||||
// Generate generates RBAC manifests by parsing the RBAC annotations in Go source
|
||||
// files specified in the input directory.
|
||||
func Generate(o *Options) error {
|
||||
if err := o.WriterOptions.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := general.ParseDir(o.InputDir, o.parseAnnotation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse the input dir: %v", err)
|
||||
}
|
||||
|
||||
if len(o.webhooks) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
objs, err := o.Generate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = o.WriteObjectsToDisk(objs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return o.controllerManagerPatch()
|
||||
}
|
||||
|
||||
func (o *Options) controllerManagerPatch() error {
|
||||
var kustomizeLabelPatch = `apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: controller-manager
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Labels }}
|
||||
labels:
|
||||
{{ toYaml . | indent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
containers:
|
||||
- name: manager
|
||||
ports:
|
||||
- containerPort: {{ .Port }}
|
||||
name: webhook-server
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: {{ .CertDir }}
|
||||
name: cert
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cert
|
||||
secret:
|
||||
defaultMode: 420
|
||||
secretName: {{ .SecretName }}
|
||||
`
|
||||
|
||||
type KustomizeLabelPatch struct {
|
||||
Labels map[string]string
|
||||
SecretName string
|
||||
Port int32
|
||||
CertDir string
|
||||
}
|
||||
|
||||
p := KustomizeLabelPatch{
|
||||
Labels: o.service.selectors,
|
||||
SecretName: o.secret.Name,
|
||||
Port: o.port,
|
||||
CertDir: o.certDir,
|
||||
}
|
||||
funcMap := template.FuncMap{
|
||||
"toYaml": toYAML,
|
||||
"indent": indent,
|
||||
}
|
||||
temp, err := template.New("kustomizeLabelPatch").Funcs(funcMap).Parse(kustomizeLabelPatch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err := temp.Execute(buf, p); err != nil {
|
||||
return err
|
||||
}
|
||||
return afero.WriteFile(o.outFs, path.Join(o.PatchOutputDir, "manager_patch.yaml"), buf.Bytes(), 0644)
|
||||
}
|
||||
|
||||
func toYAML(m map[string]string) (string, error) {
|
||||
d, err := yaml.Marshal(m)
|
||||
return string(d), err
|
||||
}
|
||||
|
||||
func indent(n int, s string) (string, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
for _, elem := range strings.Split(s, "\n") {
|
||||
for i := 0; i < n; i++ {
|
||||
_, err := buf.WriteRune(' ')
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
_, err := buf.WriteString(elem)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = buf.WriteRune('\n')
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return strings.TrimRight(buf.String(), " \n"), nil
|
||||
}
|
||||
404
vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go
generated
vendored
404
vendor/sigs.k8s.io/controller-tools/pkg/webhook/parser.go
generated
vendored
@@ -14,223 +14,237 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package webhook contains libraries for generating webhookconfig manifests
|
||||
// from markers in Go source files.
|
||||
//
|
||||
// The markers take the form:
|
||||
//
|
||||
// +kubebuilder:webhook:failurePolicy=<string>,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=<string>,path=<string>,mutating=<bool>
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"sigs.k8s.io/controller-tools/pkg/internal/general"
|
||||
)
|
||||
admissionreg "k8s.io/api/admissionregistration/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
const webhookAnnotationPrefix = "kubebuilder:webhook"
|
||||
"sigs.k8s.io/controller-tools/pkg/genall"
|
||||
"sigs.k8s.io/controller-tools/pkg/markers"
|
||||
)
|
||||
|
||||
var (
|
||||
webhookTags = sets.NewString([]string{"groups", "versions", "resources", "verbs", "type", "name", "path", "failure-policy"}...)
|
||||
serverTags = sets.NewString([]string{"port", "cert-dir", "service", "selector", "secret", "host", "mutating-webhook-config-name", "validating-webhook-config-name"}...)
|
||||
// ConfigDefinition s 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{}))
|
||||
)
|
||||
|
||||
// parseAnnotation parses webhook annotations
|
||||
func (o *Options) parseAnnotation(commentText string) error {
|
||||
webhookKVMap, serverKVMap := map[string]string{}, map[string]string{}
|
||||
for _, comment := range strings.Split(commentText, "\n") {
|
||||
comment := strings.TrimSpace(comment)
|
||||
anno := general.GetAnnotation(comment, webhookAnnotationPrefix)
|
||||
if len(anno) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, elem := range strings.Split(anno, ",") {
|
||||
key, value, err := general.ParseKV(elem)
|
||||
if err != nil {
|
||||
log.Fatalf("// +kubebuilder:webhook: tags must be key value pairs. Example "+
|
||||
"keys [groups=<group1;group2>,resources=<resource1;resource2>,verbs=<verb1;verb2>] "+
|
||||
"Got string: [%s]", anno)
|
||||
}
|
||||
switch {
|
||||
case webhookTags.Has(key):
|
||||
webhookKVMap[key] = value
|
||||
case serverTags.Has(key):
|
||||
serverKVMap[key] = value
|
||||
}
|
||||
// +controllertools:marker:generateHelp:category=Webhook
|
||||
|
||||
// Config specifies how a webhook should be served.
|
||||
//
|
||||
// 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).
|
||||
type Config 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
|
||||
// FailurePolicy specifies what should happen if the API server cannot reach the webhook.
|
||||
//
|
||||
// It may be either "ignore" (to skip the webhook and continue on) or "fail" (to reject
|
||||
// the object in question).
|
||||
FailurePolicy string
|
||||
|
||||
// Groups specifies the API groups that this webhook receives requests for.
|
||||
Groups []string
|
||||
// Resources specifies the API resources that this webhook receives requests for.
|
||||
Resources []string
|
||||
// Verbs specifies the Kubernetes API verbs that this webhook receives requests for.
|
||||
//
|
||||
// Only modification-like verbs may be specified.
|
||||
// May be "create", "update", "delete", "connect", or "*" (for all).
|
||||
Verbs []string
|
||||
// Versions specifies the API versions that this webhook receives requests for.
|
||||
Versions []string
|
||||
|
||||
// Name indicates the name of this webhook configuration.
|
||||
Name string
|
||||
// Path specifies that path that the API server should connect to this webhook on.
|
||||
Path string
|
||||
}
|
||||
|
||||
// verbToAPIVariant converts a marker's verb to the proper value for the API.
|
||||
// Unrecognized verbs are passed through.
|
||||
func verbToAPIVariant(verbRaw string) admissionreg.OperationType {
|
||||
switch strings.ToLower(verbRaw) {
|
||||
case strings.ToLower(string(admissionreg.Create)):
|
||||
return admissionreg.Create
|
||||
case strings.ToLower(string(admissionreg.Update)):
|
||||
return admissionreg.Update
|
||||
case strings.ToLower(string(admissionreg.Delete)):
|
||||
return admissionreg.Delete
|
||||
case strings.ToLower(string(admissionreg.Connect)):
|
||||
return admissionreg.Connect
|
||||
case strings.ToLower(string(admissionreg.OperationAll)):
|
||||
return admissionreg.OperationAll
|
||||
default:
|
||||
return admissionreg.OperationType(verbRaw)
|
||||
}
|
||||
}
|
||||
|
||||
// ToMutatingWebhook converts this rule to its Kubernetes API form.
|
||||
func (c Config) ToMutatingWebhook() (admissionreg.MutatingWebhook, error) {
|
||||
if !c.Mutating {
|
||||
return admissionreg.MutatingWebhook{}, fmt.Errorf("%s is a validating webhook", c.Name)
|
||||
}
|
||||
|
||||
return admissionreg.MutatingWebhook{
|
||||
Name: c.Name,
|
||||
Rules: c.rules(),
|
||||
FailurePolicy: c.failurePolicy(),
|
||||
ClientConfig: c.clientConfig(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ToValidatingWebhook converts this rule to its Kubernetes API form.
|
||||
func (c Config) ToValidatingWebhook() (admissionreg.ValidatingWebhook, error) {
|
||||
if c.Mutating {
|
||||
return admissionreg.ValidatingWebhook{}, fmt.Errorf("%s is a mutating webhook", c.Name)
|
||||
}
|
||||
|
||||
return admissionreg.ValidatingWebhook{
|
||||
Name: c.Name,
|
||||
Rules: c.rules(),
|
||||
FailurePolicy: c.failurePolicy(),
|
||||
ClientConfig: c.clientConfig(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// rules returns the configuration of what operations on what
|
||||
// resources/subresources a webhook should care about.
|
||||
func (c Config) rules() []admissionreg.RuleWithOperations {
|
||||
whConfig := admissionreg.RuleWithOperations{
|
||||
Rule: admissionreg.Rule{
|
||||
APIGroups: c.Groups,
|
||||
APIVersions: c.Versions,
|
||||
Resources: c.Resources,
|
||||
},
|
||||
Operations: make([]admissionreg.OperationType, len(c.Verbs)),
|
||||
}
|
||||
|
||||
for i, verbRaw := range c.Verbs {
|
||||
whConfig.Operations[i] = verbToAPIVariant(verbRaw)
|
||||
}
|
||||
|
||||
// fix the group names, since letting people type "core" is nice
|
||||
for i, group := range whConfig.APIGroups {
|
||||
if group == "core" {
|
||||
whConfig.APIGroups[i] = ""
|
||||
}
|
||||
}
|
||||
|
||||
if err := o.parseWebhookAnnotation(webhookKVMap); err != nil {
|
||||
return []admissionreg.RuleWithOperations{whConfig}
|
||||
}
|
||||
|
||||
// failurePolicy converts the string value to the proper value for the API.
|
||||
// Unrecognized values are passed through.
|
||||
func (c Config) failurePolicy() *admissionreg.FailurePolicyType {
|
||||
var failurePolicy admissionreg.FailurePolicyType
|
||||
switch strings.ToLower(c.FailurePolicy) {
|
||||
case strings.ToLower(string(admissionreg.Ignore)):
|
||||
failurePolicy = admissionreg.Ignore
|
||||
case strings.ToLower(string(admissionreg.Fail)):
|
||||
failurePolicy = admissionreg.Fail
|
||||
default:
|
||||
failurePolicy = admissionreg.FailurePolicyType(c.FailurePolicy)
|
||||
}
|
||||
return &failurePolicy
|
||||
}
|
||||
|
||||
// clientConfig returns the client config for a webhook.
|
||||
func (c Config) clientConfig() admissionreg.WebhookClientConfig {
|
||||
path := c.Path
|
||||
return admissionreg.WebhookClientConfig{
|
||||
Service: &admissionreg.ServiceReference{
|
||||
Name: "webhook-service",
|
||||
Namespace: "system",
|
||||
Path: &path,
|
||||
},
|
||||
// OpenAPI marks the field as required before 1.13 because of a bug that got fixed in
|
||||
// https://github.com/kubernetes/api/commit/e7d9121e9ffd63cea0288b36a82bcc87b073bd1b
|
||||
// Put "\n" as an placeholder as a workaround til 1.13+ is almost everywhere.
|
||||
CABundle: []byte("\n"),
|
||||
}
|
||||
}
|
||||
|
||||
// +controllertools:marker:generateHelp
|
||||
|
||||
// Generator generates (partial) {Mutating,Validating}WebhookConfiguration objects.
|
||||
type Generator struct{}
|
||||
|
||||
func (Generator) RegisterMarkers(into *markers.Registry) error {
|
||||
if err := into.Register(ConfigDefinition); err != nil {
|
||||
return err
|
||||
}
|
||||
return o.parseServerAnnotation(serverKVMap)
|
||||
}
|
||||
|
||||
// parseWebhookAnnotation parses webhook annotations in the same comment group
|
||||
// nolint: gocyclo
|
||||
func (o *Options) parseWebhookAnnotation(kvMap map[string]string) error {
|
||||
if len(kvMap) == 0 {
|
||||
return nil
|
||||
}
|
||||
rule := admissionregistrationv1beta1.RuleWithOperations{}
|
||||
w := &admissionWebhook{}
|
||||
for key, value := range kvMap {
|
||||
switch key {
|
||||
case "groups":
|
||||
values := strings.Split(value, ";")
|
||||
normalized := []string{}
|
||||
for _, v := range values {
|
||||
if v == "core" {
|
||||
normalized = append(normalized, "")
|
||||
} else {
|
||||
normalized = append(normalized, v)
|
||||
}
|
||||
}
|
||||
rule.APIGroups = values
|
||||
|
||||
case "versions":
|
||||
values := strings.Split(value, ";")
|
||||
rule.APIVersions = values
|
||||
|
||||
case "resources":
|
||||
values := strings.Split(value, ";")
|
||||
rule.Resources = values
|
||||
|
||||
case "verbs":
|
||||
values := strings.Split(value, ";")
|
||||
var ops []admissionregistrationv1beta1.OperationType
|
||||
for _, v := range values {
|
||||
switch strings.ToLower(v) {
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.Create)):
|
||||
ops = append(ops, admissionregistrationv1beta1.Create)
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.Update)):
|
||||
ops = append(ops, admissionregistrationv1beta1.Update)
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.Delete)):
|
||||
ops = append(ops, admissionregistrationv1beta1.Delete)
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.Connect)):
|
||||
ops = append(ops, admissionregistrationv1beta1.Connect)
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.OperationAll)):
|
||||
ops = append(ops, admissionregistrationv1beta1.OperationAll)
|
||||
default:
|
||||
return fmt.Errorf("unknown operation: %v", v)
|
||||
}
|
||||
}
|
||||
rule.Operations = ops
|
||||
|
||||
case "type":
|
||||
switch strings.ToLower(value) {
|
||||
case "mutating":
|
||||
w.typ = mutatingWebhook
|
||||
case "validating":
|
||||
w.typ = validatingWebhook
|
||||
default:
|
||||
return fmt.Errorf("unknown webhook type: %v", value)
|
||||
}
|
||||
|
||||
case "name":
|
||||
w.name = value
|
||||
|
||||
case "path":
|
||||
w.path = value
|
||||
|
||||
case "failure-policy":
|
||||
switch strings.ToLower(value) {
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.Ignore)):
|
||||
fp := admissionregistrationv1beta1.Ignore
|
||||
w.failurePolicy = &fp
|
||||
case strings.ToLower(string(admissionregistrationv1beta1.Fail)):
|
||||
fp := admissionregistrationv1beta1.Fail
|
||||
w.failurePolicy = &fp
|
||||
default:
|
||||
return fmt.Errorf("unknown webhook failure policy: %v", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
w.rules = []admissionregistrationv1beta1.RuleWithOperations{rule}
|
||||
if o.webhooks == nil {
|
||||
o.webhooks = map[string]webhook{}
|
||||
}
|
||||
o.webhooks[w.path] = w
|
||||
into.AddHelp(ConfigDefinition, Config{}.Help())
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseWebhookAnnotation parses webhook server annotations in the same comment group
|
||||
// nolint: gocyclo
|
||||
func (o *Options) parseServerAnnotation(kvMap map[string]string) error {
|
||||
if len(kvMap) == 0 {
|
||||
return nil
|
||||
}
|
||||
for key, value := range kvMap {
|
||||
switch key {
|
||||
case "port":
|
||||
port, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.port = int32(port)
|
||||
case "cert-dir":
|
||||
o.certDir = value
|
||||
case "service":
|
||||
// format: <service=namespace:name>
|
||||
split := strings.Split(value, ":")
|
||||
if len(split) != 2 || len(split[0]) == 0 || len(split[1]) == 0 {
|
||||
return fmt.Errorf("invalid service format: expect <namespace:name>, but got %q", value)
|
||||
}
|
||||
if o.service == nil {
|
||||
o.service = &service{}
|
||||
}
|
||||
o.service.namespace = split[0]
|
||||
o.service.name = split[1]
|
||||
case "selector":
|
||||
// selector of the service. Format: <selector=label1:value1;label2:value2>
|
||||
split := strings.Split(value, ";")
|
||||
if len(split) == 0 {
|
||||
return fmt.Errorf("invalid selector format: expect <label1:value1;label2:value2>, but got %q", value)
|
||||
}
|
||||
if o.service == nil {
|
||||
o.service = &service{}
|
||||
}
|
||||
for _, v := range split {
|
||||
l := strings.Split(v, ":")
|
||||
if len(l) != 2 || len(l[0]) == 0 || len(l[1]) == 0 {
|
||||
return fmt.Errorf("invalid selector format: expect <label1:value1;label2:value2>, but got %q", value)
|
||||
}
|
||||
if o.service.selectors == nil {
|
||||
o.service.selectors = map[string]string{}
|
||||
}
|
||||
o.service.selectors[l[0]] = l[1]
|
||||
}
|
||||
case "host":
|
||||
if len(value) == 0 {
|
||||
return errors.New("host should not be empty if specified")
|
||||
}
|
||||
o.host = &value
|
||||
func (Generator) Generate(ctx *genall.GenerationContext) error {
|
||||
var mutatingCfgs []admissionreg.MutatingWebhook
|
||||
var validatingCfgs []admissionreg.ValidatingWebhook
|
||||
for _, root := range ctx.Roots {
|
||||
markerSet, err := markers.PackageMarkers(ctx.Collector, root)
|
||||
if err != nil {
|
||||
root.AddError(err)
|
||||
}
|
||||
|
||||
case "mutating-webhook-config-name":
|
||||
if len(value) == 0 {
|
||||
return errors.New("mutating-webhook-config-name should not be empty if specified")
|
||||
for _, cfg := range markerSet[ConfigDefinition.Name] {
|
||||
cfg := cfg.(Config)
|
||||
if cfg.Mutating {
|
||||
w, _ := cfg.ToMutatingWebhook()
|
||||
mutatingCfgs = append(mutatingCfgs, w)
|
||||
} else {
|
||||
w, _ := cfg.ToValidatingWebhook()
|
||||
validatingCfgs = append(validatingCfgs, w)
|
||||
}
|
||||
o.mutatingWebhookConfigName = value
|
||||
|
||||
case "validating-webhook-config-name":
|
||||
if len(value) == 0 {
|
||||
return errors.New("validating-webhook-config-name should not be empty if specified")
|
||||
}
|
||||
o.validatingWebhookConfigName = value
|
||||
|
||||
case "secret":
|
||||
// format: <secret=namespace:name>
|
||||
split := strings.Split(value, ":")
|
||||
if len(split) != 2 || len(split[0]) == 0 || len(split[1]) == 0 {
|
||||
return fmt.Errorf("invalid secret format: expect <namespace:name>, but got %q", value)
|
||||
}
|
||||
if o.secret == nil {
|
||||
o.secret = &types.NamespacedName{}
|
||||
}
|
||||
o.secret.Namespace = split[0]
|
||||
o.secret.Name = split[1]
|
||||
}
|
||||
}
|
||||
|
||||
var objs []interface{}
|
||||
if len(mutatingCfgs) > 0 {
|
||||
objs = append(objs, &admissionreg.MutatingWebhookConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "MutatingWebhookConfiguration",
|
||||
APIVersion: admissionreg.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "mutating-webhook-configuration",
|
||||
},
|
||||
Webhooks: mutatingCfgs,
|
||||
})
|
||||
}
|
||||
|
||||
if len(validatingCfgs) > 0 {
|
||||
objs = append(objs, &admissionreg.ValidatingWebhookConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ValidatingWebhookConfiguration",
|
||||
APIVersion: admissionreg.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "validating-webhook-configuration",
|
||||
},
|
||||
Webhooks: validatingCfgs,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if err := ctx.WriteYAML("manifests.yaml", objs...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
38
vendor/sigs.k8s.io/controller-tools/pkg/webhook/types.go
generated
vendored
38
vendor/sigs.k8s.io/controller-tools/pkg/webhook/types.go
generated
vendored
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 webhook
|
||||
|
||||
// webhookType defines the type of a webhook
|
||||
type webhookType int
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
// mutatingWebhook represents mutating type webhook
|
||||
mutatingWebhook webhookType = iota
|
||||
// validatingWebhook represents validating type webhook
|
||||
validatingWebhook
|
||||
)
|
||||
|
||||
// webhook defines the basics that a webhook should support.
|
||||
type webhook interface {
|
||||
// GetType returns the Type of the webhook.
|
||||
// e.g. mutating or validating
|
||||
GetType() webhookType
|
||||
// Validate validates if the webhook itself is valid.
|
||||
// If invalid, a non-nil error will be returned.
|
||||
Validate() error
|
||||
}
|
||||
92
vendor/sigs.k8s.io/controller-tools/pkg/webhook/writer.go
generated
vendored
92
vendor/sigs.k8s.io/controller-tools/pkg/webhook/writer.go
generated
vendored
@@ -1,92 +0,0 @@
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// WriterOptions specifies the input and output.
|
||||
type WriterOptions struct {
|
||||
InputDir string
|
||||
OutputDir string
|
||||
PatchOutputDir string
|
||||
|
||||
// inFs is filesystem to be used for reading input
|
||||
inFs afero.Fs
|
||||
// outFs is filesystem to be used for writing out the result
|
||||
outFs afero.Fs
|
||||
}
|
||||
|
||||
// SetDefaults sets up the default options for RBAC Manifest generator.
|
||||
func (o *WriterOptions) SetDefaults() {
|
||||
if o.inFs == nil {
|
||||
o.inFs = afero.NewOsFs()
|
||||
}
|
||||
if o.outFs == nil {
|
||||
o.outFs = afero.NewOsFs()
|
||||
}
|
||||
|
||||
if len(o.InputDir) == 0 {
|
||||
o.InputDir = filepath.Join(".", "pkg", "webhook")
|
||||
}
|
||||
if len(o.OutputDir) == 0 {
|
||||
o.OutputDir = filepath.Join(".", "config", "webhook")
|
||||
}
|
||||
if len(o.PatchOutputDir) == 0 {
|
||||
o.PatchOutputDir = filepath.Join(".", "config", "default")
|
||||
}
|
||||
}
|
||||
|
||||
// Validate validates the input options.
|
||||
func (o *WriterOptions) Validate() error {
|
||||
if _, err := o.inFs.Stat(o.InputDir); err != nil {
|
||||
return fmt.Errorf("invalid input directory '%s' %v", o.InputDir, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteObjectsToDisk writes object to the location specified in WriterOptions.
|
||||
func (o *WriterOptions) WriteObjectsToDisk(objects ...runtime.Object) error {
|
||||
exists, err := afero.DirExists(o.outFs, o.OutputDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
err = o.outFs.MkdirAll(o.OutputDir, 0766)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
isFirstObject := true
|
||||
for _, obj := range objects {
|
||||
if !isFirstObject {
|
||||
_, err = buf.WriteString("---\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
marshalled, err := yaml.Marshal(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = buf.Write(marshalled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
isFirstObject = false
|
||||
}
|
||||
err = afero.WriteFile(o.outFs, path.Join(o.OutputDir, "webhookmanifests.yaml"), buf.Bytes(), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
80
vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go
generated
vendored
Normal file
80
vendor/sigs.k8s.io/controller-tools/pkg/webhook/zz_generated.markerhelp.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright2019 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.
|
||||
*/
|
||||
|
||||
// Code generated by helpgen. DO NOT EDIT.
|
||||
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/controller-tools/pkg/markers"
|
||||
)
|
||||
|
||||
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).",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{
|
||||
"Mutating": markers.DetailedHelp{
|
||||
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.",
|
||||
},
|
||||
"FailurePolicy": markers.DetailedHelp{
|
||||
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).",
|
||||
},
|
||||
"Groups": markers.DetailedHelp{
|
||||
Summary: "specifies the API groups that this webhook receives requests for.",
|
||||
Details: "",
|
||||
},
|
||||
"Resources": markers.DetailedHelp{
|
||||
Summary: "specifies the API resources that this webhook receives requests for.",
|
||||
Details: "",
|
||||
},
|
||||
"Verbs": markers.DetailedHelp{
|
||||
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).",
|
||||
},
|
||||
"Versions": markers.DetailedHelp{
|
||||
Summary: "specifies the API versions that this webhook receives requests for.",
|
||||
Details: "",
|
||||
},
|
||||
"Name": markers.DetailedHelp{
|
||||
Summary: "indicates the name of this webhook configuration.",
|
||||
Details: "",
|
||||
},
|
||||
"Path": markers.DetailedHelp{
|
||||
Summary: "specifies that path that the API server should connect to this webhook on.",
|
||||
Details: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (Generator) Help() *markers.DefinitionHelp {
|
||||
return &markers.DefinitionHelp{
|
||||
Category: "",
|
||||
DetailedHelp: markers.DetailedHelp{
|
||||
Summary: "generates (partial) {Mutating,Validating}WebhookConfiguration objects.",
|
||||
Details: "",
|
||||
},
|
||||
FieldHelp: map[string]markers.DetailedHelp{},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user