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:
hongming
2023-02-08 14:06:15 +08:00
committed by GitHub
parent 129e6fbec3
commit 1c49fcd57e
1404 changed files with 141422 additions and 47769 deletions

View 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"

View 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
}

View 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"

View 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
}

View 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
}