k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo_test.go (about) 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 }