mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
Merge pull request #67798 from mbohlool/crd_refactoring
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md. Refactor admission webhook client code to a apiserver/pkg/util package As part of #67006 This refactoring enable us to share code between admission webhooks and CRD conversion webhooks. @deads2k @lavalamp @sttts @kubernetes/sig-api-machinery-misc
This commit is contained in:
commit
14eb029fba
@ -54,7 +54,6 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||||
@ -68,6 +67,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/storage/etcd3/preflight:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage/etcd3/preflight:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/discovery/cached:go_default_library",
|
"//staging/src/k8s.io/client-go/discovery/cached:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
|
@ -42,7 +42,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
utilwait "k8s.io/apimachinery/pkg/util/wait"
|
utilwait "k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
webhookconfig "k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
|
||||||
webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer"
|
webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
@ -54,6 +53,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/storage/etcd3/preflight"
|
"k8s.io/apiserver/pkg/storage/etcd3/preflight"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
apiserverflag "k8s.io/apiserver/pkg/util/flag"
|
apiserverflag "k8s.io/apiserver/pkg/util/flag"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
cacheddiscovery "k8s.io/client-go/discovery/cached"
|
cacheddiscovery "k8s.io/client-go/discovery/cached"
|
||||||
clientgoinformers "k8s.io/client-go/informers"
|
clientgoinformers "k8s.io/client-go/informers"
|
||||||
clientgoclientset "k8s.io/client-go/kubernetes"
|
clientgoclientset "k8s.io/client-go/kubernetes"
|
||||||
@ -539,8 +539,8 @@ func buildGenericConfig(
|
|||||||
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
|
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookAuthResolverWrapper := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver {
|
webhookAuthResolverWrapper := func(delegate webhook.AuthenticationInfoResolver) webhook.AuthenticationInfoResolver {
|
||||||
return &webhookconfig.AuthenticationInfoResolverDelegator{
|
return &webhook.AuthenticationInfoResolverDelegator{
|
||||||
ClientConfigForFunc: func(server string) (*rest.Config, error) {
|
ClientConfigForFunc: func(server string) (*rest.Config, error) {
|
||||||
if server == "kubernetes.default.svc" {
|
if server == "kubernetes.default.svc" {
|
||||||
return genericConfig.LoopbackClientConfig, nil
|
return genericConfig.LoopbackClientConfig, nil
|
||||||
@ -593,7 +593,7 @@ func BuildAdmissionPluginInitializers(
|
|||||||
client internalclientset.Interface,
|
client internalclientset.Interface,
|
||||||
sharedInformers informers.SharedInformerFactory,
|
sharedInformers informers.SharedInformerFactory,
|
||||||
serviceResolver aggregatorapiserver.ServiceResolver,
|
serviceResolver aggregatorapiserver.ServiceResolver,
|
||||||
webhookAuthWrapper webhookconfig.AuthenticationInfoResolverWrapper,
|
webhookAuthWrapper webhook.AuthenticationInfoResolverWrapper,
|
||||||
) ([]admission.PluginInitializer, genericapiserver.PostStartHookFunc, error) {
|
) ([]admission.PluginInitializer, genericapiserver.PostStartHookFunc, error) {
|
||||||
var cloudConfig []byte
|
var cloudConfig []byte
|
||||||
|
|
||||||
|
@ -550,7 +550,6 @@ staging/src/k8s.io/apiserver/pkg/admission/configuration
|
|||||||
staging/src/k8s.io/apiserver/pkg/admission/initializer
|
staging/src/k8s.io/apiserver/pkg/admission/initializer
|
||||||
staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization
|
staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization
|
||||||
staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle
|
staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle
|
||||||
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config
|
|
||||||
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission
|
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission
|
||||||
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1
|
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1
|
||||||
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating
|
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating
|
||||||
|
@ -23,8 +23,8 @@ go_library(
|
|||||||
"//pkg/quota:go_default_library",
|
"//pkg/quota:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@ package admission
|
|||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
webhookconfig "k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/quota"
|
"k8s.io/kubernetes/pkg/quota"
|
||||||
@ -64,8 +64,8 @@ type PluginInitializer struct {
|
|||||||
cloudConfig []byte
|
cloudConfig []byte
|
||||||
restMapper meta.RESTMapper
|
restMapper meta.RESTMapper
|
||||||
quotaConfiguration quota.Configuration
|
quotaConfiguration quota.Configuration
|
||||||
serviceResolver webhookconfig.ServiceResolver
|
serviceResolver webhook.ServiceResolver
|
||||||
authenticationInfoResolverWrapper webhookconfig.AuthenticationInfoResolverWrapper
|
authenticationInfoResolverWrapper webhook.AuthenticationInfoResolverWrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ admission.PluginInitializer = &PluginInitializer{}
|
var _ admission.PluginInitializer = &PluginInitializer{}
|
||||||
|
@ -60,6 +60,7 @@ filegroup(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation:all-srcs",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation:all-srcs",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:all-srcs",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:all-srcs",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/waitgroup:all-srcs",
|
"//staging/src/k8s.io/apimachinery/pkg/util/waitgroup:all-srcs",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/webhook:all-srcs",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:all-srcs",
|
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:all-srcs",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/version:all-srcs",
|
"//staging/src/k8s.io/apimachinery/pkg/version:all-srcs",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:all-srcs",
|
"//staging/src/k8s.io/apimachinery/pkg/watch:all-srcs",
|
||||||
|
@ -1234,6 +1234,10 @@
|
|||||||
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules",
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/util",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating",
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
13
staging/src/k8s.io/apimachinery/pkg/util/webhook/BUILD
Normal file
13
staging/src/k8s.io/apimachinery/pkg/util/webhook/BUILD
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
@ -90,6 +90,7 @@ filegroup(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/rules:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/rules:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testcerts:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testcerts:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testing:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testing:all-srcs",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/util:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating:all-srcs",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating:all-srcs",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
|
@ -1,46 +1,18 @@
|
|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = ["kubeconfig.go"],
|
||||||
"authentication.go",
|
|
||||||
"client.go",
|
|
||||||
"kubeconfig.go",
|
|
||||||
"serviceresolver.go",
|
|
||||||
],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config",
|
||||||
importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/config",
|
importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/config",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
|
||||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = [
|
|
||||||
"authentication_test.go",
|
|
||||||
"serviceresolver_test.go",
|
|
||||||
],
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"errors.go",
|
|
||||||
"statuserror.go",
|
"statuserror.go",
|
||||||
],
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/errors",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/errors",
|
||||||
|
@ -11,6 +11,7 @@ go_library(
|
|||||||
importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/generic",
|
importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/generic",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
@ -20,6 +21,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/namespace:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/namespace:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/rules:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/rules:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||||
"k8s.io/api/admissionregistration/v1beta1"
|
"k8s.io/api/admissionregistration/v1beta1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/namespace"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/namespace"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/rules"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/rules"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
)
|
)
|
||||||
@ -40,7 +42,7 @@ type Webhook struct {
|
|||||||
sourceFactory sourceFactory
|
sourceFactory sourceFactory
|
||||||
|
|
||||||
hookSource Source
|
hookSource Source
|
||||||
clientManager *config.ClientManager
|
clientManager *webhook.ClientManager
|
||||||
convertor *convertor
|
convertor *convertor
|
||||||
namespaceMatcher *namespace.Matcher
|
namespaceMatcher *namespace.Matcher
|
||||||
dispatcher Dispatcher
|
dispatcher Dispatcher
|
||||||
@ -52,7 +54,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type sourceFactory func(f informers.SharedInformerFactory) Source
|
type sourceFactory func(f informers.SharedInformerFactory) Source
|
||||||
type dispatcherFactory func(cm *config.ClientManager) Dispatcher
|
type dispatcherFactory func(cm *webhook.ClientManager) Dispatcher
|
||||||
|
|
||||||
// NewWebhook creates a new generic admission webhook.
|
// NewWebhook creates a new generic admission webhook.
|
||||||
func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory sourceFactory, dispatcherFactory dispatcherFactory) (*Webhook, error) {
|
func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory sourceFactory, dispatcherFactory dispatcherFactory) (*Webhook, error) {
|
||||||
@ -61,17 +63,17 @@ func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, err := config.NewClientManager()
|
cm, err := webhook.NewClientManager(admissionv1beta1.SchemeGroupVersion, admissionv1beta1.AddToScheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
authInfoResolver, err := config.NewDefaultAuthenticationInfoResolver(kubeconfigFile)
|
authInfoResolver, err := webhook.NewDefaultAuthenticationInfoResolver(kubeconfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Set defaults which may be overridden later.
|
// Set defaults which may be overridden later.
|
||||||
cm.SetAuthenticationInfoResolver(authInfoResolver)
|
cm.SetAuthenticationInfoResolver(authInfoResolver)
|
||||||
cm.SetServiceResolver(config.NewDefaultServiceResolver())
|
cm.SetServiceResolver(webhook.NewDefaultServiceResolver())
|
||||||
|
|
||||||
return &Webhook{
|
return &Webhook{
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
@ -86,13 +88,13 @@ func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory
|
|||||||
// SetAuthenticationInfoResolverWrapper sets the
|
// SetAuthenticationInfoResolverWrapper sets the
|
||||||
// AuthenticationInfoResolverWrapper.
|
// AuthenticationInfoResolverWrapper.
|
||||||
// TODO find a better way wire this, but keep this pull small for now.
|
// TODO find a better way wire this, but keep this pull small for now.
|
||||||
func (a *Webhook) SetAuthenticationInfoResolverWrapper(wrapper config.AuthenticationInfoResolverWrapper) {
|
func (a *Webhook) SetAuthenticationInfoResolverWrapper(wrapper webhook.AuthenticationInfoResolverWrapper) {
|
||||||
a.clientManager.SetAuthenticationInfoResolverWrapper(wrapper)
|
a.clientManager.SetAuthenticationInfoResolverWrapper(wrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetServiceResolver sets a service resolver for the webhook admission plugin.
|
// SetServiceResolver sets a service resolver for the webhook admission plugin.
|
||||||
// Passing a nil resolver does not have an effect, instead a default one will be used.
|
// Passing a nil resolver does not have an effect, instead a default one will be used.
|
||||||
func (a *Webhook) SetServiceResolver(sr config.ServiceResolver) {
|
func (a *Webhook) SetServiceResolver(sr webhook.ServiceResolver) {
|
||||||
a.clientManager.SetServiceResolver(sr)
|
a.clientManager.SetServiceResolver(sr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,13 +20,13 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
webhookconfig "k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WantsServiceResolver defines a function that accepts a ServiceResolver for
|
// WantsServiceResolver defines a function that accepts a ServiceResolver for
|
||||||
// admission plugins that need to make calls to services.
|
// admission plugins that need to make calls to services.
|
||||||
type WantsServiceResolver interface {
|
type WantsServiceResolver interface {
|
||||||
SetServiceResolver(webhookconfig.ServiceResolver)
|
SetServiceResolver(webhook.ServiceResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceResolver knows how to convert a service reference into an actual
|
// ServiceResolver knows how to convert a service reference into an actual
|
||||||
@ -38,22 +38,22 @@ type ServiceResolver interface {
|
|||||||
// WantsAuthenticationInfoResolverWrapper defines a function that wraps the standard AuthenticationInfoResolver
|
// WantsAuthenticationInfoResolverWrapper defines a function that wraps the standard AuthenticationInfoResolver
|
||||||
// to allow the apiserver to control what is returned as auth info
|
// to allow the apiserver to control what is returned as auth info
|
||||||
type WantsAuthenticationInfoResolverWrapper interface {
|
type WantsAuthenticationInfoResolverWrapper interface {
|
||||||
SetAuthenticationInfoResolverWrapper(webhookconfig.AuthenticationInfoResolverWrapper)
|
SetAuthenticationInfoResolverWrapper(wrapper webhook.AuthenticationInfoResolverWrapper)
|
||||||
admission.InitializationValidator
|
admission.InitializationValidator
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginInitializer is used for initialization of the webhook admission plugin.
|
// PluginInitializer is used for initialization of the webhook admission plugin.
|
||||||
type PluginInitializer struct {
|
type PluginInitializer struct {
|
||||||
serviceResolver webhookconfig.ServiceResolver
|
serviceResolver webhook.ServiceResolver
|
||||||
authenticationInfoResolverWrapper webhookconfig.AuthenticationInfoResolverWrapper
|
authenticationInfoResolverWrapper webhook.AuthenticationInfoResolverWrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ admission.PluginInitializer = &PluginInitializer{}
|
var _ admission.PluginInitializer = &PluginInitializer{}
|
||||||
|
|
||||||
// NewPluginInitializer constructs new instance of PluginInitializer
|
// NewPluginInitializer constructs new instance of PluginInitializer
|
||||||
func NewPluginInitializer(
|
func NewPluginInitializer(
|
||||||
authenticationInfoResolverWrapper webhookconfig.AuthenticationInfoResolverWrapper,
|
authenticationInfoResolverWrapper webhook.AuthenticationInfoResolverWrapper,
|
||||||
serviceResolver webhookconfig.ServiceResolver,
|
serviceResolver webhook.ServiceResolver,
|
||||||
) *PluginInitializer {
|
) *PluginInitializer {
|
||||||
return &PluginInitializer{
|
return &PluginInitializer{
|
||||||
authenticationInfoResolverWrapper: authenticationInfoResolverWrapper,
|
authenticationInfoResolverWrapper: authenticationInfoResolverWrapper,
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
type doNothingAdmission struct{}
|
type doNothingAdmission struct{}
|
||||||
@ -39,7 +39,7 @@ type serviceWanter struct {
|
|||||||
got ServiceResolver
|
got ServiceResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceWanter) SetServiceResolver(sr config.ServiceResolver) { s.got = sr }
|
func (s *serviceWanter) SetServiceResolver(sr webhook.ServiceResolver) { s.got = sr }
|
||||||
|
|
||||||
func TestWantsServiceResolver(t *testing.T) {
|
func TestWantsServiceResolver(t *testing.T) {
|
||||||
sw := &serviceWanter{}
|
sw := &serviceWanter{}
|
||||||
|
@ -21,10 +21,11 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/configuration:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/configuration:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/metrics:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/util:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -33,19 +33,20 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
|
||||||
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
||||||
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/util"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mutatingDispatcher struct {
|
type mutatingDispatcher struct {
|
||||||
cm *config.ClientManager
|
cm *webhook.ClientManager
|
||||||
plugin *Plugin
|
plugin *Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMutatingDispatcher(p *Plugin) func(cm *config.ClientManager) generic.Dispatcher {
|
func newMutatingDispatcher(p *Plugin) func(cm *webhook.ClientManager) generic.Dispatcher {
|
||||||
return func(cm *config.ClientManager) generic.Dispatcher {
|
return func(cm *webhook.ClientManager) generic.Dispatcher {
|
||||||
return &mutatingDispatcher{cm, p}
|
return &mutatingDispatcher{cm, p}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr *generic.Version
|
|||||||
}
|
}
|
||||||
|
|
||||||
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
||||||
if callErr, ok := err.(*webhookerrors.ErrCallingWebhook); ok {
|
if callErr, ok := err.(*webhook.ErrCallingWebhook); ok {
|
||||||
if ignoreClientCallFailures {
|
if ignoreClientCallFailures {
|
||||||
glog.Warningf("Failed calling webhook, failing open %v: %v", hook.Name, callErr)
|
glog.Warningf("Failed calling webhook, failing open %v: %v", hook.Name, callErr)
|
||||||
utilruntime.HandleError(callErr)
|
utilruntime.HandleError(callErr)
|
||||||
@ -84,7 +85,7 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr *generic.Version
|
|||||||
func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta1.Webhook, attr *generic.VersionedAttributes) error {
|
func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta1.Webhook, attr *generic.VersionedAttributes) error {
|
||||||
if attr.IsDryRun() {
|
if attr.IsDryRun() {
|
||||||
if h.SideEffects == nil {
|
if h.SideEffects == nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil")}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil")}
|
||||||
}
|
}
|
||||||
if !(*h.SideEffects == v1beta1.SideEffectClassNone || *h.SideEffects == v1beta1.SideEffectClassNoneOnDryRun) {
|
if !(*h.SideEffects == v1beta1.SideEffectClassNone || *h.SideEffects == v1beta1.SideEffectClassNoneOnDryRun) {
|
||||||
return webhookerrors.NewDryRunUnsupportedErr(h.Name)
|
return webhookerrors.NewDryRunUnsupportedErr(h.Name)
|
||||||
@ -93,17 +94,17 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
|||||||
|
|
||||||
// Make the webhook request
|
// Make the webhook request
|
||||||
request := request.CreateAdmissionReview(attr)
|
request := request.CreateAdmissionReview(attr)
|
||||||
client, err := a.cm.HookClient(h)
|
client, err := a.cm.HookClient(util.HookClientConfigForWebhook(h))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
||||||
}
|
}
|
||||||
response := &admissionv1beta1.AdmissionReview{}
|
response := &admissionv1beta1.AdmissionReview{}
|
||||||
if err := client.Post().Context(ctx).Body(&request).Do().Into(response); err != nil {
|
if err := client.Post().Context(ctx).Body(&request).Do().Into(response); err != nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
if response.Response == nil {
|
if response.Response == nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook response was absent")}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook response was absent")}
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range response.Response.AuditAnnotations {
|
for k, v := range response.Response.AuditAnnotations {
|
||||||
|
@ -20,9 +20,9 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testcerts:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testcerts:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||||
|
@ -19,22 +19,22 @@ package testing
|
|||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/testcerts"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/testcerts"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wrapper turns an AuthenticationInfoResolver into a AuthenticationInfoResolverWrapper that unconditionally
|
// Wrapper turns an AuthenticationInfoResolver into a AuthenticationInfoResolverWrapper that unconditionally
|
||||||
// returns the given AuthenticationInfoResolver.
|
// returns the given AuthenticationInfoResolver.
|
||||||
func Wrapper(r config.AuthenticationInfoResolver) func(config.AuthenticationInfoResolver) config.AuthenticationInfoResolver {
|
func Wrapper(r webhook.AuthenticationInfoResolver) func(webhook.AuthenticationInfoResolver) webhook.AuthenticationInfoResolver {
|
||||||
return func(config.AuthenticationInfoResolver) config.AuthenticationInfoResolver {
|
return func(webhook.AuthenticationInfoResolver) webhook.AuthenticationInfoResolver {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAuthenticationInfoResolver creates a fake AuthenticationInfoResolver that counts cache misses on
|
// NewAuthenticationInfoResolver creates a fake AuthenticationInfoResolver that counts cache misses on
|
||||||
// every call to its methods.
|
// every call to its methods.
|
||||||
func NewAuthenticationInfoResolver(cacheMisses *int32) config.AuthenticationInfoResolver {
|
func NewAuthenticationInfoResolver(cacheMisses *int32) webhook.AuthenticationInfoResolver {
|
||||||
return &authenticationInfoResolver{
|
return &authenticationInfoResolver{
|
||||||
restConfig: &rest.Config{
|
restConfig: &rest.Config{
|
||||||
TLSClientConfig: rest.TLSClientConfig{
|
TLSClientConfig: rest.TLSClientConfig{
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
type serviceResolver struct {
|
type serviceResolver struct {
|
||||||
@ -29,7 +29,7 @@ type serviceResolver struct {
|
|||||||
|
|
||||||
// NewServiceResolver returns a static service resolve that return the given URL or
|
// NewServiceResolver returns a static service resolve that return the given URL or
|
||||||
// an error for the failResolve namespace.
|
// an error for the failResolve namespace.
|
||||||
func NewServiceResolver(base url.URL) config.ServiceResolver {
|
func NewServiceResolver(base url.URL) webhook.ServiceResolver {
|
||||||
return &serviceResolver{base}
|
return &serviceResolver{base}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["client_config.go"],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/util",
|
||||||
|
importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/util",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
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 util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/api/admissionregistration/v1beta1"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HookClientConfigForWebhook construct a webhook.ClientConfig using a v1beta1.Webhook API object.
|
||||||
|
// webhook.ClientConfig is used to create a HookClient and the purpose of the config struct is to
|
||||||
|
// share that with other packages that need to create a HookClient.
|
||||||
|
func HookClientConfigForWebhook(w *v1beta1.Webhook) webhook.ClientConfig {
|
||||||
|
ret := webhook.ClientConfig{Name: w.Name, CABundle: w.ClientConfig.CABundle}
|
||||||
|
if w.ClientConfig.URL != nil {
|
||||||
|
ret.URL = *w.ClientConfig.URL
|
||||||
|
}
|
||||||
|
if w.ClientConfig.Service != nil {
|
||||||
|
ret.Service = &webhook.ClientConfigService{
|
||||||
|
Name: w.ClientConfig.Service.Name,
|
||||||
|
Namespace: w.ClientConfig.Service.Namespace,
|
||||||
|
}
|
||||||
|
if w.ClientConfig.Service.Path != nil {
|
||||||
|
ret.Service.Path = *w.ClientConfig.Service.Path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
@ -18,10 +18,11 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/configuration:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/configuration:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/metrics:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/generic:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/util:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -29,17 +29,18 @@ import (
|
|||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
|
||||||
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/request"
|
||||||
|
"k8s.io/apiserver/pkg/admission/plugin/webhook/util"
|
||||||
|
"k8s.io/apiserver/pkg/util/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
type validatingDispatcher struct {
|
type validatingDispatcher struct {
|
||||||
cm *config.ClientManager
|
cm *webhook.ClientManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func newValidatingDispatcher(cm *config.ClientManager) generic.Dispatcher {
|
func newValidatingDispatcher(cm *webhook.ClientManager) generic.Dispatcher {
|
||||||
return &validatingDispatcher{cm}
|
return &validatingDispatcher{cm}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr *generic.Versi
|
|||||||
}
|
}
|
||||||
|
|
||||||
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1beta1.Ignore
|
||||||
if callErr, ok := err.(*webhookerrors.ErrCallingWebhook); ok {
|
if callErr, ok := err.(*webhook.ErrCallingWebhook); ok {
|
||||||
if ignoreClientCallFailures {
|
if ignoreClientCallFailures {
|
||||||
glog.Warningf("Failed calling webhook, failing open %v: %v", hook.Name, callErr)
|
glog.Warningf("Failed calling webhook, failing open %v: %v", hook.Name, callErr)
|
||||||
utilruntime.HandleError(callErr)
|
utilruntime.HandleError(callErr)
|
||||||
@ -99,7 +100,7 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr *generic.Versi
|
|||||||
func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Webhook, attr *generic.VersionedAttributes) error {
|
func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Webhook, attr *generic.VersionedAttributes) error {
|
||||||
if attr.IsDryRun() {
|
if attr.IsDryRun() {
|
||||||
if h.SideEffects == nil {
|
if h.SideEffects == nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil")}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil")}
|
||||||
}
|
}
|
||||||
if !(*h.SideEffects == v1beta1.SideEffectClassNone || *h.SideEffects == v1beta1.SideEffectClassNoneOnDryRun) {
|
if !(*h.SideEffects == v1beta1.SideEffectClassNone || *h.SideEffects == v1beta1.SideEffectClassNoneOnDryRun) {
|
||||||
return webhookerrors.NewDryRunUnsupportedErr(h.Name)
|
return webhookerrors.NewDryRunUnsupportedErr(h.Name)
|
||||||
@ -108,17 +109,17 @@ func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Webhook,
|
|||||||
|
|
||||||
// Make the webhook request
|
// Make the webhook request
|
||||||
request := request.CreateAdmissionReview(attr)
|
request := request.CreateAdmissionReview(attr)
|
||||||
client, err := d.cm.HookClient(h)
|
client, err := d.cm.HookClient(util.HookClientConfigForWebhook(h))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
||||||
}
|
}
|
||||||
response := &admissionv1beta1.AdmissionReview{}
|
response := &admissionv1beta1.AdmissionReview{}
|
||||||
if err := client.Post().Context(ctx).Body(&request).Do().Into(response); err != nil {
|
if err := client.Post().Context(ctx).Body(&request).Do().Into(response); err != nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
if response.Response == nil {
|
if response.Response == nil {
|
||||||
return &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook response was absent")}
|
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook response was absent")}
|
||||||
}
|
}
|
||||||
for k, v := range response.Response.AuditAnnotations {
|
for k, v := range response.Response.AuditAnnotations {
|
||||||
key := h.Name + "/" + k
|
key := h.Name + "/" + k
|
||||||
|
@ -8,7 +8,13 @@ load(
|
|||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["webhook.go"],
|
srcs = [
|
||||||
|
"authentication.go",
|
||||||
|
"client.go",
|
||||||
|
"error.go",
|
||||||
|
"serviceresolver.go",
|
||||||
|
"webhook.go",
|
||||||
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/util/webhook",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/util/webhook",
|
||||||
importpath = "k8s.io/apiserver/pkg/util/webhook",
|
importpath = "k8s.io/apiserver/pkg/util/webhook",
|
||||||
deps = [
|
deps = [
|
||||||
@ -16,26 +22,34 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||||
|
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"authentication_test.go",
|
||||||
"certs_test.go",
|
"certs_test.go",
|
||||||
|
"serviceresolver_test.go",
|
||||||
"webhook_test.go",
|
"webhook_test.go",
|
||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package config
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -47,10 +47,12 @@ type AuthenticationInfoResolverDelegator struct {
|
|||||||
ClientConfigForServiceFunc func(serviceName, serviceNamespace string) (*rest.Config, error)
|
ClientConfigForServiceFunc func(serviceName, serviceNamespace string) (*rest.Config, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientConfigFor returns client config for given server.
|
||||||
func (a *AuthenticationInfoResolverDelegator) ClientConfigFor(server string) (*rest.Config, error) {
|
func (a *AuthenticationInfoResolverDelegator) ClientConfigFor(server string) (*rest.Config, error) {
|
||||||
return a.ClientConfigForFunc(server)
|
return a.ClientConfigForFunc(server)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientConfigForService returns client config for given service.
|
||||||
func (a *AuthenticationInfoResolverDelegator) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) {
|
func (a *AuthenticationInfoResolverDelegator) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) {
|
||||||
return a.ClientConfigForServiceFunc(serviceName, serviceNamespace)
|
return a.ClientConfigForServiceFunc(serviceName, serviceNamespace)
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package config
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package config
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -24,13 +24,11 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
|
||||||
"k8s.io/api/admissionregistration/v1beta1"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,9 +36,20 @@ const (
|
|||||||
defaultCacheSize = 200
|
defaultCacheSize = 200
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// ClientConfig defines parameters required for creating a hook client.
|
||||||
ErrNeedServiceOrURL = errors.New("webhook configuration must have either service or URL")
|
type ClientConfig struct {
|
||||||
)
|
Name string
|
||||||
|
URL string
|
||||||
|
CABundle []byte
|
||||||
|
Service *ClientConfigService
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientConfigService defines service discovery parameters of the webhook.
|
||||||
|
type ClientConfigService struct {
|
||||||
|
Name string
|
||||||
|
Namespace string
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
// ClientManager builds REST clients to talk to webhooks. It caches the clients
|
// ClientManager builds REST clients to talk to webhooks. It caches the clients
|
||||||
// to avoid duplicate creation.
|
// to avoid duplicate creation.
|
||||||
@ -52,19 +61,19 @@ type ClientManager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClientManager creates a clientManager.
|
// NewClientManager creates a clientManager.
|
||||||
func NewClientManager() (ClientManager, error) {
|
func NewClientManager(gv schema.GroupVersion, addToSchemaFunc func(s *runtime.Scheme) error) (ClientManager, error) {
|
||||||
cache, err := lru.New(defaultCacheSize)
|
cache, err := lru.New(defaultCacheSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ClientManager{}, err
|
return ClientManager{}, err
|
||||||
}
|
}
|
||||||
admissionScheme := runtime.NewScheme()
|
admissionScheme := runtime.NewScheme()
|
||||||
if err := admissionv1beta1.AddToScheme(admissionScheme); err != nil {
|
if err := addToSchemaFunc(admissionScheme); err != nil {
|
||||||
return ClientManager{}, err
|
return ClientManager{}, err
|
||||||
}
|
}
|
||||||
return ClientManager{
|
return ClientManager{
|
||||||
cache: cache,
|
cache: cache,
|
||||||
negotiatedSerializer: serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{
|
negotiatedSerializer: serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{
|
||||||
Serializer: serializer.NewCodecFactory(admissionScheme).LegacyCodec(admissionv1beta1.SchemeGroupVersion),
|
Serializer: serializer.NewCodecFactory(admissionScheme).LegacyCodec(gv),
|
||||||
}),
|
}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -106,8 +115,10 @@ func (cm *ClientManager) Validate() error {
|
|||||||
|
|
||||||
// HookClient get a RESTClient from the cache, or constructs one based on the
|
// HookClient get a RESTClient from the cache, or constructs one based on the
|
||||||
// webhook configuration.
|
// webhook configuration.
|
||||||
func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error) {
|
func (cm *ClientManager) HookClient(cc ClientConfig) (*rest.RESTClient, error) {
|
||||||
cacheKey, err := json.Marshal(h.ClientConfig)
|
ccWithNoName := cc
|
||||||
|
ccWithNoName.Name = ""
|
||||||
|
cacheKey, err := json.Marshal(ccWithNoName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -120,7 +131,7 @@ func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error
|
|||||||
if len(cfg.TLSClientConfig.CAData) > 0 {
|
if len(cfg.TLSClientConfig.CAData) > 0 {
|
||||||
cfg.TLSClientConfig.CAData = append(cfg.TLSClientConfig.CAData, '\n')
|
cfg.TLSClientConfig.CAData = append(cfg.TLSClientConfig.CAData, '\n')
|
||||||
}
|
}
|
||||||
cfg.TLSClientConfig.CAData = append(cfg.TLSClientConfig.CAData, h.ClientConfig.CABundle...)
|
cfg.TLSClientConfig.CAData = append(cfg.TLSClientConfig.CAData, cc.CABundle...)
|
||||||
|
|
||||||
cfg.ContentConfig.NegotiatedSerializer = cm.negotiatedSerializer
|
cfg.ContentConfig.NegotiatedSerializer = cm.negotiatedSerializer
|
||||||
cfg.ContentConfig.ContentType = runtime.ContentTypeJSON
|
cfg.ContentConfig.ContentType = runtime.ContentTypeJSON
|
||||||
@ -131,18 +142,16 @@ func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error
|
|||||||
return client, err
|
return client, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if svc := h.ClientConfig.Service; svc != nil {
|
if cc.Service != nil {
|
||||||
restConfig, err := cm.authInfoResolver.ClientConfigForService(svc.Name, svc.Namespace)
|
restConfig, err := cm.authInfoResolver.ClientConfigForService(cc.Service.Name, cc.Service.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg := rest.CopyConfig(restConfig)
|
cfg := rest.CopyConfig(restConfig)
|
||||||
serverName := svc.Name + "." + svc.Namespace + ".svc"
|
serverName := cc.Service.Name + "." + cc.Service.Namespace + ".svc"
|
||||||
host := serverName + ":443"
|
host := serverName + ":443"
|
||||||
cfg.Host = "https://" + host
|
cfg.Host = "https://" + host
|
||||||
if svc.Path != nil {
|
cfg.APIPath = cc.Service.Path
|
||||||
cfg.APIPath = *svc.Path
|
|
||||||
}
|
|
||||||
// Set the server name if not already set
|
// Set the server name if not already set
|
||||||
if len(cfg.TLSClientConfig.ServerName) == 0 {
|
if len(cfg.TLSClientConfig.ServerName) == 0 {
|
||||||
cfg.TLSClientConfig.ServerName = serverName
|
cfg.TLSClientConfig.ServerName = serverName
|
||||||
@ -155,7 +164,7 @@ func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error
|
|||||||
}
|
}
|
||||||
cfg.Dial = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
cfg.Dial = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
if addr == host {
|
if addr == host {
|
||||||
u, err := cm.serviceResolver.ResolveEndpoint(svc.Namespace, svc.Name)
|
u, err := cm.serviceResolver.ResolveEndpoint(cc.Service.Namespace, cc.Service.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -167,13 +176,13 @@ func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error
|
|||||||
return complete(cfg)
|
return complete(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.ClientConfig.URL == nil {
|
if cc.URL == "" {
|
||||||
return nil, &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: ErrNeedServiceOrURL}
|
return nil, &ErrCallingWebhook{WebhookName: cc.Name, Reason: errors.New("webhook configuration must have either service or URL")}
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := url.Parse(*h.ClientConfig.URL)
|
u, err := url.Parse(cc.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Unparsable URL: %v", err)}
|
return nil, &ErrCallingWebhook{WebhookName: cc.Name, Reason: fmt.Errorf("Unparsable URL: %v", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
restConfig, err := cm.authInfoResolver.ClientConfigFor(u.Host)
|
restConfig, err := cm.authInfoResolver.ClientConfigFor(u.Host)
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package errors
|
package webhook
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package config
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -29,6 +29,7 @@ type ServiceResolver interface {
|
|||||||
|
|
||||||
type defaultServiceResolver struct{}
|
type defaultServiceResolver struct{}
|
||||||
|
|
||||||
|
// NewDefaultServiceResolver creates a new default server resolver.
|
||||||
func NewDefaultServiceResolver() ServiceResolver {
|
func NewDefaultServiceResolver() ServiceResolver {
|
||||||
return &defaultServiceResolver{}
|
return &defaultServiceResolver{}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package config
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -926,6 +926,10 @@
|
|||||||
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules",
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/util",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating",
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
@ -890,6 +890,10 @@
|
|||||||
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules",
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/util",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating",
|
"ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
Loading…
Reference in New Issue
Block a user