1
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
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