From 1df4503b859a2b7b2b7f9c5bcf400f61cc29d349 Mon Sep 17 00:00:00 2001 From: Chao Xu Date: Thu, 22 Apr 2021 23:17:39 +0000 Subject: [PATCH] Switch the order of adding SNICert and creating LoopbackClientConfig --- .../server/options/serving_with_loopback.go | 6 ++- .../options/serving_with_loopback_test.go | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback_test.go diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go b/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go index 9f9a42f81b0..2317be82d26 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback.go @@ -60,10 +60,14 @@ func (s *SecureServingOptionsWithLoopback) ApplyTo(secureServingInfo **server.Se return fmt.Errorf("failed to generate self-signed certificate for loopback connection: %v", err) } + // Write to the front of SNICerts so that this overrides any other certs with the same name + (*secureServingInfo).SNICerts = append([]dynamiccertificates.SNICertKeyContentProvider{certProvider}, (*secureServingInfo).SNICerts...) + secureLoopbackClientConfig, err := (*secureServingInfo).NewLoopbackClientConfig(uuid.New().String(), certPem) switch { // if we failed and there's no fallback loopback client config, we need to fail case err != nil && *loopbackClientConfig == nil: + (*secureServingInfo).SNICerts = (*secureServingInfo).SNICerts[1:] return err // if we failed, but we already have a fallback loopback client config (usually insecure), allow it @@ -71,8 +75,6 @@ func (s *SecureServingOptionsWithLoopback) ApplyTo(secureServingInfo **server.Se default: *loopbackClientConfig = secureLoopbackClientConfig - // Write to the front of SNICerts so that this overrides any other certs with the same name - (*secureServingInfo).SNICerts = append([]dynamiccertificates.SNICertKeyContentProvider{certProvider}, (*secureServingInfo).SNICerts...) } return nil diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback_test.go b/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback_test.go new file mode 100644 index 00000000000..f87b2fafe44 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/server/options/serving_with_loopback_test.go @@ -0,0 +1,51 @@ +/* +Copyright 2021 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 options + +import ( + "net" + "testing" + + "k8s.io/apiserver/pkg/server" + "k8s.io/client-go/rest" +) + +func TestEmptyMainCert(t *testing.T) { + secureServingInfo := &server.SecureServingInfo{} + var loopbackClientConfig *rest.Config + + s := (&SecureServingOptions{ + BindAddress: net.ParseIP("127.0.0.1"), + }).WithLoopback() + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("failed to listen on 127.0.0.1:0") + } + defer ln.Close() + s.Listener = ln + s.BindPort = ln.Addr().(*net.TCPAddr).Port + + if err := s.ApplyTo(&secureServingInfo, &loopbackClientConfig); err != nil { + t.Errorf("unexpected error: %v", err) + } + if loopbackClientConfig == nil { + t.Errorf("unexpected empty loopbackClientConfig") + } + if e, a := 1, len(secureServingInfo.SNICerts); e != a { + t.Errorf("expected %d SNICert, got %d", e, a) + } +}