remove exist client hooks
This commit is contained in:
		@@ -313,27 +313,9 @@ func CreateKubeAPIServerConfig(
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clientCA, err := readCAorNil(s.Authentication.ClientCert.ClientCA)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	requestHeaderProxyCA, err := readCAorNil(s.Authentication.RequestHeader.ClientCAFile)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	config := &master.Config{
 | 
						config := &master.Config{
 | 
				
			||||||
		GenericConfig: genericConfig,
 | 
							GenericConfig: genericConfig,
 | 
				
			||||||
		ExtraConfig: master.ExtraConfig{
 | 
							ExtraConfig: master.ExtraConfig{
 | 
				
			||||||
			ClientCARegistrationHook: master.ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				ClientCA:                         clientCA,
 | 
					 | 
				
			||||||
				RequestHeaderUsernameHeaders:     s.Authentication.RequestHeader.UsernameHeaders,
 | 
					 | 
				
			||||||
				RequestHeaderGroupHeaders:        s.Authentication.RequestHeader.GroupHeaders,
 | 
					 | 
				
			||||||
				RequestHeaderExtraHeaderPrefixes: s.Authentication.RequestHeader.ExtraHeaderPrefixes,
 | 
					 | 
				
			||||||
				RequestHeaderCA:                  requestHeaderProxyCA,
 | 
					 | 
				
			||||||
				RequestHeaderAllowedNames:        s.Authentication.RequestHeader.AllowedNames,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			APIResourceConfigSource: storageFactory.APIResourceConfigSource,
 | 
								APIResourceConfigSource: storageFactory.APIResourceConfigSource,
 | 
				
			||||||
			StorageFactory:          storageFactory,
 | 
								StorageFactory:          storageFactory,
 | 
				
			||||||
			EventTTL:                s.EventTTL,
 | 
								EventTTL:                s.EventTTL,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
 | 
				
			|||||||
go_library(
 | 
					go_library(
 | 
				
			||||||
    name = "go_default_library",
 | 
					    name = "go_default_library",
 | 
				
			||||||
    srcs = [
 | 
					    srcs = [
 | 
				
			||||||
        "client_ca_hook.go",
 | 
					 | 
				
			||||||
        "client_util.go",
 | 
					        "client_util.go",
 | 
				
			||||||
        "controller.go",
 | 
					        "controller.go",
 | 
				
			||||||
        "doc.go",
 | 
					        "doc.go",
 | 
				
			||||||
@@ -109,7 +108,6 @@ go_library(
 | 
				
			|||||||
        "//staging/src/k8s.io/api/storage/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/api/storage/v1alpha1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1alpha1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
 | 
				
			||||||
        "//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/apis/meta/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
 | 
				
			||||||
@@ -141,7 +139,6 @@ go_test(
 | 
				
			|||||||
    size = "medium",
 | 
					    size = "medium",
 | 
				
			||||||
    timeout = "long",
 | 
					    timeout = "long",
 | 
				
			||||||
    srcs = [
 | 
					    srcs = [
 | 
				
			||||||
        "client_ca_hook_test.go",
 | 
					 | 
				
			||||||
        "controller_test.go",
 | 
					        "controller_test.go",
 | 
				
			||||||
        "import_known_versions_test.go",
 | 
					        "import_known_versions_test.go",
 | 
				
			||||||
        "master_openapi_test.go",
 | 
					        "master_openapi_test.go",
 | 
				
			||||||
@@ -166,9 +163,7 @@ go_test(
 | 
				
			|||||||
        "//staging/src/k8s.io/api/core/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/api/core/v1:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/naming:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/naming:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1: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/apimachinery/pkg/util/intstr:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/intstr: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/sets:go_default_library",
 | 
					        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,142 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
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 master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	corev1 "k8s.io/api/core/v1"
 | 
					 | 
				
			||||||
	apiequality "k8s.io/apimachinery/pkg/api/equality"
 | 
					 | 
				
			||||||
	apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
					 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
					 | 
				
			||||||
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
					 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
					 | 
				
			||||||
	genericapiserver "k8s.io/apiserver/pkg/server"
 | 
					 | 
				
			||||||
	corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ClientCARegistrationHook defines CA registration hook request structure
 | 
					 | 
				
			||||||
type ClientCARegistrationHook struct {
 | 
					 | 
				
			||||||
	ClientCA []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	RequestHeaderUsernameHeaders     []string
 | 
					 | 
				
			||||||
	RequestHeaderGroupHeaders        []string
 | 
					 | 
				
			||||||
	RequestHeaderExtraHeaderPrefixes []string
 | 
					 | 
				
			||||||
	RequestHeaderCA                  []byte
 | 
					 | 
				
			||||||
	RequestHeaderAllowedNames        []string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PostStartHook initializes client CA configmap for the API server
 | 
					 | 
				
			||||||
func (h ClientCARegistrationHook) PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
 | 
					 | 
				
			||||||
	// initializing CAs is important so that aggregated API servers can come up with "normal" config.
 | 
					 | 
				
			||||||
	// We've seen lagging etcd before, so we want to retry this a few times before we decide to crashloop
 | 
					 | 
				
			||||||
	// the API server on it.
 | 
					 | 
				
			||||||
	err := wait.Poll(1*time.Second, 30*time.Second, func() (done bool, err error) {
 | 
					 | 
				
			||||||
		// retry building the config since sometimes the server can be in an in-between state which caused
 | 
					 | 
				
			||||||
		// some kind of auto detection failure as I recall from other post start hooks.
 | 
					 | 
				
			||||||
		// TODO see if this is still true and fix the RBAC one too if it isn't.
 | 
					 | 
				
			||||||
		client, err := corev1client.NewForConfig(hookContext.LoopbackClientConfig)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			utilruntime.HandleError(err)
 | 
					 | 
				
			||||||
			return false, nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return h.tryToWriteClientCAs(client)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// if we're never able to make it through initialization, kill the API server
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("unable to initialize client CA configmap: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// tryToWriteClientCAs is here for unit testing with a fake client.  This is a wait.ConditionFunc so the bool
 | 
					 | 
				
			||||||
// indicates if the condition was met.  True when its finished, false when it should retry.
 | 
					 | 
				
			||||||
func (h ClientCARegistrationHook) tryToWriteClientCAs(client corev1client.CoreV1Interface) (bool, error) {
 | 
					 | 
				
			||||||
	if err := createNamespaceIfNeeded(client, metav1.NamespaceSystem); err != nil {
 | 
					 | 
				
			||||||
		utilruntime.HandleError(err)
 | 
					 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data := map[string]string{}
 | 
					 | 
				
			||||||
	if len(h.ClientCA) > 0 {
 | 
					 | 
				
			||||||
		data["client-ca-file"] = string(h.ClientCA)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(h.RequestHeaderCA) > 0 {
 | 
					 | 
				
			||||||
		var err error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// encoding errors aren't going to get better, so just fail on them.
 | 
					 | 
				
			||||||
		data["requestheader-username-headers"], err = jsonSerializeStringSlice(h.RequestHeaderUsernameHeaders)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return false, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		data["requestheader-group-headers"], err = jsonSerializeStringSlice(h.RequestHeaderGroupHeaders)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return false, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		data["requestheader-extra-headers-prefix"], err = jsonSerializeStringSlice(h.RequestHeaderExtraHeaderPrefixes)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return false, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		data["requestheader-client-ca-file"] = string(h.RequestHeaderCA)
 | 
					 | 
				
			||||||
		data["requestheader-allowed-names"], err = jsonSerializeStringSlice(h.RequestHeaderAllowedNames)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return false, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// write errors may work next time if we retry, so queue for retry
 | 
					 | 
				
			||||||
	if err := writeConfigMap(client, "extension-apiserver-authentication", data); err != nil {
 | 
					 | 
				
			||||||
		utilruntime.HandleError(err)
 | 
					 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func jsonSerializeStringSlice(in []string) (string, error) {
 | 
					 | 
				
			||||||
	out, err := json.Marshal(in)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return string(out), err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func writeConfigMap(client corev1client.ConfigMapsGetter, name string, data map[string]string) error {
 | 
					 | 
				
			||||||
	existing, err := client.ConfigMaps(metav1.NamespaceSystem).Get(name, metav1.GetOptions{})
 | 
					 | 
				
			||||||
	if apierrors.IsNotFound(err) {
 | 
					 | 
				
			||||||
		_, err := client.ConfigMaps(metav1.NamespaceSystem).Create(&corev1.ConfigMap{
 | 
					 | 
				
			||||||
			ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: name},
 | 
					 | 
				
			||||||
			Data:       data,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !apiequality.Semantic.DeepEqual(existing.Data, data) {
 | 
					 | 
				
			||||||
		existing.Data = data
 | 
					 | 
				
			||||||
		_, err = client.ConfigMaps(metav1.NamespaceSystem).Update(existing)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,247 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
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 master
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"reflect"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	corev1 "k8s.io/api/core/v1"
 | 
					 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
					 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
					 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/diff"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/kubernetes/fake"
 | 
					 | 
				
			||||||
	clienttesting "k8s.io/client-go/testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestWriteClientCAs(t *testing.T) {
 | 
					 | 
				
			||||||
	tests := []struct {
 | 
					 | 
				
			||||||
		name               string
 | 
					 | 
				
			||||||
		hook               ClientCARegistrationHook
 | 
					 | 
				
			||||||
		preexistingObjs    []runtime.Object
 | 
					 | 
				
			||||||
		expectedConfigMaps map[string]*corev1.ConfigMap
 | 
					 | 
				
			||||||
		expectUpdate       bool
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "basic",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				ClientCA:                         []byte("foo"),
 | 
					 | 
				
			||||||
				RequestHeaderUsernameHeaders:     []string{"alfa", "bravo", "charlie"},
 | 
					 | 
				
			||||||
				RequestHeaderGroupHeaders:        []string{"delta"},
 | 
					 | 
				
			||||||
				RequestHeaderExtraHeaderPrefixes: []string{"echo", "foxtrot"},
 | 
					 | 
				
			||||||
				RequestHeaderCA:                  []byte("bar"),
 | 
					 | 
				
			||||||
				RequestHeaderAllowedNames:        []string{"first", "second"},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"client-ca-file":                     "foo",
 | 
					 | 
				
			||||||
						"requestheader-username-headers":     `["alfa","bravo","charlie"]`,
 | 
					 | 
				
			||||||
						"requestheader-group-headers":        `["delta"]`,
 | 
					 | 
				
			||||||
						"requestheader-extra-headers-prefix": `["echo","foxtrot"]`,
 | 
					 | 
				
			||||||
						"requestheader-client-ca-file":       "bar",
 | 
					 | 
				
			||||||
						"requestheader-allowed-names":        `["first","second"]`,
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "skip extension-apiserver-authentication",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				RequestHeaderCA:           []byte("bar"),
 | 
					 | 
				
			||||||
				RequestHeaderAllowedNames: []string{"first", "second"},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"requestheader-username-headers":     `null`,
 | 
					 | 
				
			||||||
						"requestheader-group-headers":        `null`,
 | 
					 | 
				
			||||||
						"requestheader-extra-headers-prefix": `null`,
 | 
					 | 
				
			||||||
						"requestheader-client-ca-file":       "bar",
 | 
					 | 
				
			||||||
						"requestheader-allowed-names":        `["first","second"]`,
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "skip extension-apiserver-authentication",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				ClientCA: []byte("foo"),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"client-ca-file": "foo",
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "empty allowed names",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				RequestHeaderCA: []byte("bar"),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"requestheader-username-headers":     `null`,
 | 
					 | 
				
			||||||
						"requestheader-group-headers":        `null`,
 | 
					 | 
				
			||||||
						"requestheader-extra-headers-prefix": `null`,
 | 
					 | 
				
			||||||
						"requestheader-client-ca-file":       "bar",
 | 
					 | 
				
			||||||
						"requestheader-allowed-names":        `null`,
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "overwrite extension-apiserver-authentication",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				ClientCA: []byte("foo"),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			preexistingObjs: []runtime.Object{
 | 
					 | 
				
			||||||
				&corev1.ConfigMap{
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"client-ca-file": "other",
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"client-ca-file": "foo",
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectUpdate: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "overwrite extension-apiserver-authentication requestheader",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				RequestHeaderUsernameHeaders:     []string{},
 | 
					 | 
				
			||||||
				RequestHeaderGroupHeaders:        []string{},
 | 
					 | 
				
			||||||
				RequestHeaderExtraHeaderPrefixes: []string{},
 | 
					 | 
				
			||||||
				RequestHeaderCA:                  []byte("bar"),
 | 
					 | 
				
			||||||
				RequestHeaderAllowedNames:        []string{},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			preexistingObjs: []runtime.Object{
 | 
					 | 
				
			||||||
				&corev1.ConfigMap{
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"requestheader-username-headers":     `null`,
 | 
					 | 
				
			||||||
						"requestheader-group-headers":        `null`,
 | 
					 | 
				
			||||||
						"requestheader-extra-headers-prefix": `null`,
 | 
					 | 
				
			||||||
						"requestheader-client-ca-file":       "something",
 | 
					 | 
				
			||||||
						"requestheader-allowed-names":        `null`,
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"requestheader-username-headers":     `[]`,
 | 
					 | 
				
			||||||
						"requestheader-group-headers":        `[]`,
 | 
					 | 
				
			||||||
						"requestheader-extra-headers-prefix": `[]`,
 | 
					 | 
				
			||||||
						"requestheader-client-ca-file":       "bar",
 | 
					 | 
				
			||||||
						"requestheader-allowed-names":        `[]`,
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectUpdate: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "namespace exists",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				ClientCA: []byte("foo"),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			preexistingObjs: []runtime.Object{
 | 
					 | 
				
			||||||
				&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: metav1.NamespaceSystem}},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{
 | 
					 | 
				
			||||||
				"extension-apiserver-authentication": {
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"client-ca-file": "foo",
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "skip on no change",
 | 
					 | 
				
			||||||
			hook: ClientCARegistrationHook{
 | 
					 | 
				
			||||||
				RequestHeaderUsernameHeaders:     []string{},
 | 
					 | 
				
			||||||
				RequestHeaderGroupHeaders:        []string{},
 | 
					 | 
				
			||||||
				RequestHeaderExtraHeaderPrefixes: []string{},
 | 
					 | 
				
			||||||
				RequestHeaderCA:                  []byte("bar"),
 | 
					 | 
				
			||||||
				RequestHeaderAllowedNames:        []string{},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			preexistingObjs: []runtime.Object{
 | 
					 | 
				
			||||||
				&corev1.ConfigMap{
 | 
					 | 
				
			||||||
					ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: "extension-apiserver-authentication"},
 | 
					 | 
				
			||||||
					Data: map[string]string{
 | 
					 | 
				
			||||||
						"requestheader-username-headers":     `[]`,
 | 
					 | 
				
			||||||
						"requestheader-group-headers":        `[]`,
 | 
					 | 
				
			||||||
						"requestheader-extra-headers-prefix": `[]`,
 | 
					 | 
				
			||||||
						"requestheader-client-ca-file":       "bar",
 | 
					 | 
				
			||||||
						"requestheader-allowed-names":        `[]`,
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectedConfigMaps: map[string]*corev1.ConfigMap{},
 | 
					 | 
				
			||||||
			expectUpdate:       false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, test := range tests {
 | 
					 | 
				
			||||||
		t.Run(test.name, func(t *testing.T) {
 | 
					 | 
				
			||||||
			client := fake.NewSimpleClientset(test.preexistingObjs...)
 | 
					 | 
				
			||||||
			test.hook.tryToWriteClientCAs(client.CoreV1())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			actualConfigMaps, updated := getFinalConfigMaps(client)
 | 
					 | 
				
			||||||
			if !reflect.DeepEqual(test.expectedConfigMaps, actualConfigMaps) {
 | 
					 | 
				
			||||||
				t.Fatalf("%s: %v", test.name, diff.ObjectReflectDiff(test.expectedConfigMaps, actualConfigMaps))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if test.expectUpdate != updated {
 | 
					 | 
				
			||||||
				t.Fatalf("%s: expected %v, got %v", test.name, test.expectUpdate, updated)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getFinalConfigMaps(client *fake.Clientset) (map[string]*corev1.ConfigMap, bool) {
 | 
					 | 
				
			||||||
	ret := map[string]*corev1.ConfigMap{}
 | 
					 | 
				
			||||||
	updated := false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, action := range client.Actions() {
 | 
					 | 
				
			||||||
		if action.Matches("create", "configmaps") {
 | 
					 | 
				
			||||||
			obj := action.(clienttesting.CreateAction).GetObject().(*corev1.ConfigMap)
 | 
					 | 
				
			||||||
			ret[obj.Name] = obj
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if action.Matches("update", "configmaps") {
 | 
					 | 
				
			||||||
			updated = true
 | 
					 | 
				
			||||||
			obj := action.(clienttesting.UpdateAction).GetObject().(*corev1.ConfigMap)
 | 
					 | 
				
			||||||
			ret[obj.Name] = obj
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ret, updated
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -125,7 +125,6 @@ const (
 | 
				
			|||||||
// ExtraConfig defines extra configuration for the master
 | 
					// ExtraConfig defines extra configuration for the master
 | 
				
			||||||
type ExtraConfig struct {
 | 
					type ExtraConfig struct {
 | 
				
			||||||
	ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
 | 
						ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
 | 
				
			||||||
	ClientCARegistrationHook  ClientCARegistrationHook
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	APIResourceConfigSource  serverstorage.APIResourceConfigSource
 | 
						APIResourceConfigSource  serverstorage.APIResourceConfigSource
 | 
				
			||||||
	StorageFactory           serverstorage.StorageFactory
 | 
						StorageFactory           serverstorage.StorageFactory
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user