...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo_test.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package clusterinfo
    18  
    19  import (
    20  	"context"
    21  	"os"
    22  	"testing"
    23  	"text/template"
    24  	"time"
    25  
    26  	rbac "k8s.io/api/rbac/v1"
    27  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  	"k8s.io/apimachinery/pkg/runtime/schema"
    31  	"k8s.io/apiserver/pkg/authentication/user"
    32  	clientsetfake "k8s.io/client-go/kubernetes/fake"
    33  	core "k8s.io/client-go/testing"
    34  	bootstrapapi "k8s.io/cluster-bootstrap/token/api"
    35  
    36  	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
    37  )
    38  
    39  var testConfigTempl = template.Must(template.New("test").Parse(`apiVersion: v1
    40  clusters:
    41  - cluster:
    42      server: {{.Server}}
    43    name: kubernetes
    44  contexts:
    45  - context:
    46      cluster: kubernetes
    47      user: kubernetes-admin
    48    name: kubernetes-admin@kubernetes
    49  current-context: kubernetes-admin@kubernetes
    50  kind: Config
    51  preferences: {}
    52  users:
    53  - name: kubernetes-admin`))
    54  
    55  func TestCreateBootstrapConfigMapIfNotExists(t *testing.T) {
    56  	tests := []struct {
    57  		name      string
    58  		fileExist bool
    59  		createErr error
    60  		expectErr bool
    61  	}{
    62  		{
    63  			"successful case should have no error",
    64  			true,
    65  			nil,
    66  			false,
    67  		},
    68  		{
    69  			"if configmap already exists, return error",
    70  			true,
    71  			apierrors.NewAlreadyExists(schema.GroupResource{Resource: "configmaps"}, "test"),
    72  			true,
    73  		},
    74  		{
    75  			"unexpected error should be returned",
    76  			true,
    77  			apierrors.NewUnauthorized("go away!"),
    78  			true,
    79  		},
    80  		{
    81  			"if the file does not exist, return error",
    82  			false,
    83  			nil,
    84  			true,
    85  		},
    86  	}
    87  
    88  	servers := []struct {
    89  		Server string
    90  	}{
    91  		{Server: "https://10.128.0.6:6443"},
    92  		{Server: "https://[2001:db8::6]:3446"},
    93  	}
    94  
    95  	for _, server := range servers {
    96  		file, err := os.CreateTemp("", "")
    97  		if err != nil {
    98  			t.Fatalf("could not create tempfile: %v", err)
    99  		}
   100  		defer os.Remove(file.Name())
   101  
   102  		if err := testConfigTempl.Execute(file, server); err != nil {
   103  			t.Fatalf("could not write to tempfile: %v", err)
   104  		}
   105  
   106  		if err := file.Close(); err != nil {
   107  			t.Fatalf("could not close tempfile: %v", err)
   108  		}
   109  
   110  		// Override the default timeouts to be shorter
   111  		defaultTimeouts := kubeadmapi.GetActiveTimeouts()
   112  		defaultAPICallTimeout := defaultTimeouts.KubernetesAPICall
   113  		defaultTimeouts.KubernetesAPICall = &metav1.Duration{Duration: time.Microsecond * 500}
   114  		defer func() {
   115  			defaultTimeouts.KubernetesAPICall = defaultAPICallTimeout
   116  		}()
   117  
   118  		for _, tc := range tests {
   119  			t.Run(tc.name, func(t *testing.T) {
   120  				client := clientsetfake.NewSimpleClientset()
   121  				if tc.createErr != nil {
   122  					client.PrependReactor("create", "configmaps", func(action core.Action) (bool, runtime.Object, error) {
   123  						return true, nil, tc.createErr
   124  					})
   125  				}
   126  
   127  				fileName := file.Name()
   128  				if !tc.fileExist {
   129  					fileName = "notexistfile"
   130  				}
   131  				err := CreateBootstrapConfigMapIfNotExists(client, fileName)
   132  				if tc.expectErr && err == nil {
   133  					t.Errorf("CreateBootstrapConfigMapIfNotExists(%s) wanted error, got nil", tc.name)
   134  				} else if !tc.expectErr && err != nil {
   135  					t.Errorf("CreateBootstrapConfigMapIfNotExists(%s) returned unexpected error: %v", tc.name, err)
   136  				}
   137  			})
   138  		}
   139  	}
   140  }
   141  
   142  func TestCreateClusterInfoRBACRules(t *testing.T) {
   143  	tests := []struct {
   144  		name   string
   145  		client *clientsetfake.Clientset
   146  	}{
   147  		{
   148  			name:   "the RBAC rules already exist",
   149  			client: newMockClientForTest(t),
   150  		},
   151  		{
   152  			name:   "the RBAC rules do not exist",
   153  			client: clientsetfake.NewSimpleClientset(),
   154  		},
   155  	}
   156  	for _, tt := range tests {
   157  		t.Run(tt.name, func(t *testing.T) {
   158  			if err := CreateClusterInfoRBACRules(tt.client); err != nil {
   159  				t.Errorf("CreateClusterInfoRBACRules() hits unexpected error: %v", err)
   160  			}
   161  		})
   162  	}
   163  }
   164  
   165  func newMockClientForTest(t *testing.T) *clientsetfake.Clientset {
   166  	client := clientsetfake.NewSimpleClientset()
   167  
   168  	_, err := client.RbacV1().Roles(metav1.NamespacePublic).Create(context.TODO(), &rbac.Role{
   169  		ObjectMeta: metav1.ObjectMeta{
   170  			Name:      BootstrapSignerClusterRoleName,
   171  			Namespace: metav1.NamespacePublic,
   172  		},
   173  		Rules: []rbac.PolicyRule{
   174  			{
   175  				Verbs:         []string{"get"},
   176  				APIGroups:     []string{""},
   177  				Resources:     []string{"Secret"},
   178  				ResourceNames: []string{bootstrapapi.ConfigMapClusterInfo},
   179  			},
   180  		},
   181  	}, metav1.CreateOptions{})
   182  	if err != nil {
   183  		t.Fatalf("error creating role: %v", err)
   184  	}
   185  
   186  	_, err = client.RbacV1().RoleBindings(metav1.NamespacePublic).Create(context.TODO(), &rbac.RoleBinding{
   187  		ObjectMeta: metav1.ObjectMeta{
   188  			Name:      BootstrapSignerClusterRoleName,
   189  			Namespace: metav1.NamespacePublic,
   190  		},
   191  		RoleRef: rbac.RoleRef{
   192  			APIGroup: rbac.GroupName,
   193  			Kind:     "Role",
   194  			Name:     BootstrapSignerClusterRoleName,
   195  		},
   196  		Subjects: []rbac.Subject{
   197  			{
   198  				Kind: rbac.UserKind,
   199  				Name: user.Anonymous,
   200  			},
   201  		},
   202  	}, metav1.CreateOptions{})
   203  	if err != nil {
   204  		t.Fatalf("error creating rolebinding: %v", err)
   205  	}
   206  
   207  	return client
   208  }
   209  

View as plain text