mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Merge pull request #52673 from p0lyn0mial/webhook_default_service_resolver
Automatic merge from submit-queue (batch tested with PRs 52831, 52764, 52763, 52673, 52558). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.. default service resolver for webhook admission **What this PR does / why we need it**: provides a default service resolver for webhook plugin. The rationale behind is that webhook plugins names can be resolved by a dns server working inside a cluster. **Release note**: ``` NONE ```
This commit is contained in:
commit
7f3f986402
@ -188,9 +188,6 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) {
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsServiceResolver); ok {
|
||||
if i.serviceResolver == nil {
|
||||
panic("An admission plugin wants the service resolver, but it was not provided.")
|
||||
}
|
||||
wants.SetServiceResolver(i.serviceResolver)
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ go_test(
|
||||
"admission_test.go",
|
||||
"certs_test.go",
|
||||
"rules_test.go",
|
||||
"serviceresolver_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
@ -32,6 +33,7 @@ go_library(
|
||||
"admission.go",
|
||||
"doc.go",
|
||||
"rules.go",
|
||||
"serviceresolver.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
|
@ -97,6 +97,7 @@ func NewGenericAdmissionWebhook() (*GenericAdmissionWebhook, error) {
|
||||
negotiatedSerializer: serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{
|
||||
Serializer: api.Codecs.LegacyCodec(admissionv1alpha1.SchemeGroupVersion),
|
||||
}),
|
||||
serviceResolver: defaultServiceResolver{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -121,8 +122,12 @@ func (a *GenericAdmissionWebhook) SetProxyTransport(pt *http.Transport) {
|
||||
a.proxyTransport = pt
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (a *GenericAdmissionWebhook) SetServiceResolver(sr admissioninit.ServiceResolver) {
|
||||
a.serviceResolver = sr
|
||||
if sr != nil {
|
||||
a.serviceResolver = sr
|
||||
}
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) SetClientCert(cert, key []byte) {
|
||||
|
42
plugin/pkg/admission/webhook/serviceresolver.go
Normal file
42
plugin/pkg/admission/webhook/serviceresolver.go
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
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 webhook checks a webhook for configured operation admission
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
admissioninit "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
)
|
||||
|
||||
type defaultServiceResolver struct{}
|
||||
|
||||
var _ admissioninit.ServiceResolver = defaultServiceResolver{}
|
||||
|
||||
// ResolveEndpoint constructs a service URL from a given namespace and name
|
||||
// note that the name and namespace are required and by default all created addresses use HTTPS scheme.
|
||||
// for example:
|
||||
// name=ross namespace=andromeda resolves to https://ross.andromeda.svc
|
||||
func (sr defaultServiceResolver) ResolveEndpoint(namespace, name string) (*url.URL, error) {
|
||||
if len(name) == 0 || len(namespace) == 0 {
|
||||
return &url.URL{}, errors.New("cannot resolve an empty service name or namespace")
|
||||
}
|
||||
|
||||
return url.Parse(fmt.Sprintf("https://%s.%s.svc", name, namespace))
|
||||
}
|
57
plugin/pkg/admission/webhook/serviceresolver_test.go
Normal file
57
plugin/pkg/admission/webhook/serviceresolver_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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 webhook checks a webhook for configured operation admission
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDefaultServiceResolver(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
serviceName string
|
||||
serviceNamespace string
|
||||
expectedOutput string
|
||||
expectError bool
|
||||
}{
|
||||
// scenario 1: a service name along with a namespace resolves
|
||||
{serviceName: "ross", serviceNamespace: "andromeda", expectedOutput: "https://ross.andromeda.svc"},
|
||||
// scenario 2: a service name without a namespace does not resolve
|
||||
{serviceName: "ross", expectError: true},
|
||||
// scenario 3: cannot resolve an empty service name
|
||||
{serviceNamespace: "andromeda", expectError: true},
|
||||
}
|
||||
|
||||
// act
|
||||
for index, scenario := range scenarios {
|
||||
t.Run(fmt.Sprintf("scenario %d", index), func(t *testing.T) {
|
||||
target := defaultServiceResolver{}
|
||||
serviceURL, err := target.ResolveEndpoint(scenario.serviceNamespace, scenario.serviceName)
|
||||
|
||||
if err != nil && !scenario.expectError {
|
||||
t.Errorf("unexpected error has occurred = %v", err)
|
||||
}
|
||||
if err == nil && scenario.expectError {
|
||||
t.Error("expected an error but got nothing")
|
||||
}
|
||||
if serviceURL.String() != scenario.expectedOutput {
|
||||
t.Errorf("expected = %s, got = %s", scenario.expectedOutput, serviceURL.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user