Bump sigs.k8s.io/controller-runtime to v0.14.4 (#5507)
* Bump sigs.k8s.io/controller-runtime to v0.14.4 * Update gofmt
This commit is contained in:
20
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2017 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 namespace defines the utilities that are used by the webhook
|
||||
// plugin to decide if a webhook should be applied to an object based on its
|
||||
// namespace.
|
||||
package namespace // import "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace"
|
||||
125
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go
generated
vendored
Normal file
125
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
Copyright 2017 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 namespace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
corelisters "k8s.io/client-go/listers/core/v1"
|
||||
)
|
||||
|
||||
type NamespaceSelectorProvider interface {
|
||||
// GetNamespaceSelector gets the webhook NamespaceSelector field.
|
||||
GetParsedNamespaceSelector() (labels.Selector, error)
|
||||
}
|
||||
|
||||
// Matcher decides if a request is exempted by the NamespaceSelector of a
|
||||
// webhook configuration.
|
||||
type Matcher struct {
|
||||
NamespaceLister corelisters.NamespaceLister
|
||||
Client clientset.Interface
|
||||
}
|
||||
|
||||
// Validate checks if the Matcher has a NamespaceLister and Client.
|
||||
func (m *Matcher) Validate() error {
|
||||
var errs []error
|
||||
if m.NamespaceLister == nil {
|
||||
errs = append(errs, fmt.Errorf("the namespace matcher requires a namespaceLister"))
|
||||
}
|
||||
if m.Client == nil {
|
||||
errs = append(errs, fmt.Errorf("the namespace matcher requires a client"))
|
||||
}
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// GetNamespaceLabels gets the labels of the namespace related to the attr.
|
||||
func (m *Matcher) GetNamespaceLabels(attr admission.Attributes) (map[string]string, error) {
|
||||
// If the request itself is creating or updating a namespace, then get the
|
||||
// labels from attr.Object, because namespaceLister doesn't have the latest
|
||||
// namespace yet.
|
||||
//
|
||||
// However, if the request is deleting a namespace, then get the label from
|
||||
// the namespace in the namespaceLister, because a delete request is not
|
||||
// going to change the object, and attr.Object will be a DeleteOptions
|
||||
// rather than a namespace object.
|
||||
if attr.GetResource().Resource == "namespaces" &&
|
||||
len(attr.GetSubresource()) == 0 &&
|
||||
(attr.GetOperation() == admission.Create || attr.GetOperation() == admission.Update) {
|
||||
accessor, err := meta.Accessor(attr.GetObject())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetLabels(), nil
|
||||
}
|
||||
|
||||
namespaceName := attr.GetNamespace()
|
||||
namespace, err := m.NamespaceLister.Get(namespaceName)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if apierrors.IsNotFound(err) {
|
||||
// in case of latency in our caches, make a call direct to storage to verify that it truly exists or not
|
||||
namespace, err = m.Client.CoreV1().Namespaces().Get(context.TODO(), namespaceName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return namespace.Labels, nil
|
||||
}
|
||||
|
||||
// MatchNamespaceSelector decideds whether the request matches the
|
||||
// namespaceSelctor of the webhook. Only when they match, the webhook is called.
|
||||
func (m *Matcher) MatchNamespaceSelector(p NamespaceSelectorProvider, attr admission.Attributes) (bool, *apierrors.StatusError) {
|
||||
namespaceName := attr.GetNamespace()
|
||||
if len(namespaceName) == 0 && attr.GetResource().Resource != "namespaces" {
|
||||
// If the request is about a cluster scoped resource, and it is not a
|
||||
// namespace, it is never exempted.
|
||||
// TODO: figure out a way selective exempt cluster scoped resources.
|
||||
// Also update the comment in types.go
|
||||
return true, nil
|
||||
}
|
||||
selector, err := p.GetParsedNamespaceSelector()
|
||||
if err != nil {
|
||||
return false, apierrors.NewInternalError(err)
|
||||
}
|
||||
if selector.Empty() {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
namespaceLabels, err := m.GetNamespaceLabels(attr)
|
||||
// this means the namespace is not found, for backwards compatibility,
|
||||
// return a 404
|
||||
if apierrors.IsNotFound(err) {
|
||||
status, ok := err.(apierrors.APIStatus)
|
||||
if !ok {
|
||||
return false, apierrors.NewInternalError(err)
|
||||
}
|
||||
return false, &apierrors.StatusError{status.Status()}
|
||||
}
|
||||
if err != nil {
|
||||
return false, apierrors.NewInternalError(err)
|
||||
}
|
||||
return selector.Matches(labels.Set(namespaceLabels)), nil
|
||||
}
|
||||
20
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2019 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 object defines the utilities that are used by the webhook plugin to
|
||||
// decide if a webhook should run, as long as either the old object or the new
|
||||
// object has labels matching the webhook config's objectSelector.
|
||||
package object // import "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object"
|
||||
61
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/matcher.go
generated
vendored
Normal file
61
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object/matcher.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2019 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 object
|
||||
|
||||
import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type ObjectSelectorProvider interface {
|
||||
// GetObjectSelector gets the webhook ObjectSelector field.
|
||||
GetParsedObjectSelector() (labels.Selector, error)
|
||||
}
|
||||
|
||||
// Matcher decides if a request selected by the ObjectSelector.
|
||||
type Matcher struct {
|
||||
}
|
||||
|
||||
func matchObject(obj runtime.Object, selector labels.Selector) bool {
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
klog.V(5).InfoS("Accessing metadata failed", "object", obj, "err", err)
|
||||
return false
|
||||
}
|
||||
return selector.Matches(labels.Set(accessor.GetLabels()))
|
||||
|
||||
}
|
||||
|
||||
// MatchObjectSelector decideds whether the request matches the ObjectSelector
|
||||
// of the webhook. Only when they match, the webhook is called.
|
||||
func (m *Matcher) MatchObjectSelector(p ObjectSelectorProvider, attr admission.Attributes) (bool, *apierrors.StatusError) {
|
||||
selector, err := p.GetParsedObjectSelector()
|
||||
if err != nil {
|
||||
return false, apierrors.NewInternalError(err)
|
||||
}
|
||||
if selector.Empty() {
|
||||
return true, nil
|
||||
}
|
||||
return matchObject(attr.GetObject(), selector) || matchObject(attr.GetOldObject(), selector), nil
|
||||
}
|
||||
129
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules/rules.go
generated
vendored
Normal file
129
vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules/rules.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright 2017 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 rules
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
)
|
||||
|
||||
// Matcher determines if the Attr matches the Rule.
|
||||
type Matcher struct {
|
||||
Rule v1.RuleWithOperations
|
||||
Attr admission.Attributes
|
||||
}
|
||||
|
||||
// Matches returns if the Attr matches the Rule.
|
||||
func (r *Matcher) Matches() bool {
|
||||
return r.scope() &&
|
||||
r.operation() &&
|
||||
r.group() &&
|
||||
r.version() &&
|
||||
r.resource()
|
||||
}
|
||||
|
||||
func exactOrWildcard(items []string, requested string) bool {
|
||||
for _, item := range items {
|
||||
if item == "*" {
|
||||
return true
|
||||
}
|
||||
if item == requested {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var namespaceResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"}
|
||||
|
||||
func (r *Matcher) scope() bool {
|
||||
if r.Rule.Scope == nil || *r.Rule.Scope == v1.AllScopes {
|
||||
return true
|
||||
}
|
||||
// attr.GetNamespace() is set to the name of the namespace for requests of the namespace object itself.
|
||||
switch *r.Rule.Scope {
|
||||
case v1.NamespacedScope:
|
||||
// first make sure that we are not requesting a namespace object (namespace objects are cluster-scoped)
|
||||
return r.Attr.GetResource() != namespaceResource && r.Attr.GetNamespace() != metav1.NamespaceNone
|
||||
case v1.ClusterScope:
|
||||
// also return true if the request is for a namespace object (namespace objects are cluster-scoped)
|
||||
return r.Attr.GetResource() == namespaceResource || r.Attr.GetNamespace() == metav1.NamespaceNone
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Matcher) group() bool {
|
||||
return exactOrWildcard(r.Rule.APIGroups, r.Attr.GetResource().Group)
|
||||
}
|
||||
|
||||
func (r *Matcher) version() bool {
|
||||
return exactOrWildcard(r.Rule.APIVersions, r.Attr.GetResource().Version)
|
||||
}
|
||||
|
||||
func (r *Matcher) operation() bool {
|
||||
attrOp := r.Attr.GetOperation()
|
||||
for _, op := range r.Rule.Operations {
|
||||
if op == v1.OperationAll {
|
||||
return true
|
||||
}
|
||||
// The constants are the same such that this is a valid cast (and this
|
||||
// is tested).
|
||||
if op == v1.OperationType(attrOp) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func splitResource(resSub string) (res, sub string) {
|
||||
parts := strings.SplitN(resSub, "/", 2)
|
||||
if len(parts) == 2 {
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
return parts[0], ""
|
||||
}
|
||||
|
||||
func (r *Matcher) resource() bool {
|
||||
opRes, opSub := r.Attr.GetResource().Resource, r.Attr.GetSubresource()
|
||||
for _, res := range r.Rule.Resources {
|
||||
res, sub := splitResource(res)
|
||||
resMatch := res == "*" || res == opRes
|
||||
subMatch := sub == "*" || sub == opSub
|
||||
if resMatch && subMatch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsExemptAdmissionConfigurationResource determines if an admission.Attributes object is describing
|
||||
// the admission of a ValidatingWebhookConfiguration or a MutatingWebhookConfiguration or a ValidatingAdmissionPolicy or a ValidatingAdmissionPolicyBinding
|
||||
func IsExemptAdmissionConfigurationResource(attr admission.Attributes) bool {
|
||||
gvk := attr.GetKind()
|
||||
if gvk.Group == "admissionregistration.k8s.io" {
|
||||
if gvk.Kind == "ValidatingWebhookConfiguration" || gvk.Kind == "MutatingWebhookConfiguration" || gvk.Kind == "ValidatingAdmissionPolicy" || gvk.Kind == "ValidatingAdmissionPolicyBinding" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user