sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/services/iamauth/configmap_test.go (about) 1 /* 2 Copyright 2020 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 iamauth 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 . "github.com/onsi/gomega" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/types" 28 crclient "sigs.k8s.io/controller-runtime/pkg/client" 29 "sigs.k8s.io/controller-runtime/pkg/client/fake" 30 "sigs.k8s.io/yaml" 31 32 ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1" 33 ) 34 35 var ( 36 existingNodeRoleMap = ` 37 - groups: 38 - system:bootstrappers 39 - system:nodes 40 rolearn: arn:aws:iam::000000000000:role/KubernetesNode 41 username: system:node:{{EC2PrivateDNSName}} 42 ` 43 44 existingUserMap = ` 45 - userarn: arn:aws:iam::000000000000:user/Alice 46 username: alice 47 groups: 48 - system:masters 49 ` 50 ) 51 52 func TestAddRoleMappingCM(t *testing.T) { 53 testCases := []struct { 54 name string 55 existingAuthConfigMap *corev1.ConfigMap 56 roleToMap ekscontrolplanev1.RoleMapping 57 expectedRoleMaps []ekscontrolplanev1.RoleMapping 58 expectError bool 59 }{ 60 { 61 name: "no existing mappings, add role mapping", 62 roleToMap: ekscontrolplanev1.RoleMapping{ 63 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 64 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 65 UserName: "system:node:{{EC2PrivateDNSName}}", 66 Groups: []string{"system:bootstrappers", "system:nodes"}, 67 }, 68 }, 69 expectedRoleMaps: []ekscontrolplanev1.RoleMapping{ 70 { 71 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 72 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 73 UserName: "system:node:{{EC2PrivateDNSName}}", 74 Groups: []string{"system:bootstrappers", "system:nodes"}, 75 }, 76 }, 77 }, 78 expectError: false, 79 }, 80 { 81 name: "existing mapping, add different mapping", 82 roleToMap: ekscontrolplanev1.RoleMapping{ 83 RoleARN: "arn:aws:iam::000000000000:role/KubernetesAdmin", 84 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 85 UserName: "admin:{{SessionName}}", 86 Groups: []string{"system:masters"}, 87 }, 88 }, 89 expectedRoleMaps: []ekscontrolplanev1.RoleMapping{ 90 { 91 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 92 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 93 UserName: "system:node:{{EC2PrivateDNSName}}", 94 Groups: []string{"system:bootstrappers", "system:nodes"}, 95 }, 96 }, 97 { 98 RoleARN: "arn:aws:iam::000000000000:role/KubernetesAdmin", 99 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 100 UserName: "admin:{{SessionName}}", 101 Groups: []string{"system:masters"}, 102 }, 103 }, 104 }, 105 expectError: false, 106 existingAuthConfigMap: createFakeConfigMap(existingNodeRoleMap, ""), 107 }, 108 { 109 name: "existing mapping, add same mapping", 110 roleToMap: ekscontrolplanev1.RoleMapping{ 111 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 112 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 113 UserName: "system:node:{{EC2PrivateDNSName}}", 114 Groups: []string{"system:bootstrappers", "system:nodes"}, 115 }, 116 }, 117 expectedRoleMaps: []ekscontrolplanev1.RoleMapping{ 118 { 119 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 120 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 121 UserName: "system:node:{{EC2PrivateDNSName}}", 122 Groups: []string{"system:bootstrappers", "system:nodes"}, 123 }, 124 }, 125 }, 126 expectError: false, 127 existingAuthConfigMap: createFakeConfigMap(existingNodeRoleMap, ""), 128 }, 129 } 130 131 for _, tc := range testCases { 132 t.Run(tc.name, func(t *testing.T) { 133 g := NewGomegaWithT(t) 134 135 var client crclient.Client 136 if tc.existingAuthConfigMap == nil { 137 client = fake.NewClientBuilder().Build() 138 } else { 139 client = fake.NewClientBuilder().WithObjects(tc.existingAuthConfigMap).Build() 140 } 141 backend, err := NewBackend(BackendTypeConfigMap, client) 142 g.Expect(err).To(BeNil()) 143 144 err = backend.MapRole(tc.roleToMap) 145 if tc.expectError { 146 g.Expect(err).ToNot(BeNil()) 147 return 148 } 149 150 g.Expect(err).To(BeNil()) 151 152 key := types.NamespacedName{ 153 Name: "aws-auth", 154 Namespace: "kube-system", 155 } 156 157 cm := &corev1.ConfigMap{} 158 159 err = client.Get(context.TODO(), key, cm) 160 g.Expect(err).To(BeNil()) 161 162 g.Expect(cm.Name).To(Equal("aws-auth")) 163 g.Expect(cm.Namespace).To(Equal("kube-system")) 164 g.Expect(cm.Data).ToNot(BeNil()) 165 166 actualRoleMappings, roleMappingsFound := cm.Data["mapRoles"] 167 if len(tc.expectedRoleMaps) == 0 { 168 g.Expect(roleMappingsFound).To(BeFalse()) 169 } else { 170 roles := []ekscontrolplanev1.RoleMapping{} 171 err := yaml.Unmarshal([]byte(actualRoleMappings), &roles) 172 g.Expect(err).To(BeNil()) 173 g.Expect(len(roles)).To(Equal(len(tc.expectedRoleMaps))) 174 //TODO: we may need to do a better match 175 bothMatch := cmp.Equal(roles, tc.expectedRoleMaps) 176 g.Expect(bothMatch).To(BeTrue()) 177 } 178 179 _, userMappingsFound := cm.Data["mapUsers"] 180 g.Expect(userMappingsFound).To(BeFalse()) 181 }) 182 } 183 } 184 185 func TestAddUserMappingCM(t *testing.T) { 186 testCases := []struct { 187 name string 188 existingAuthConfigMap *corev1.ConfigMap 189 userToMap ekscontrolplanev1.UserMapping 190 expectedUsersMap []ekscontrolplanev1.UserMapping 191 expectError bool 192 }{ 193 { 194 name: "no existing user mappings, add user mapping", 195 userToMap: ekscontrolplanev1.UserMapping{ 196 UserARN: "arn:aws:iam::000000000000:user/Alice", 197 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 198 UserName: "alice", 199 Groups: []string{"system:masters"}, 200 }, 201 }, 202 expectedUsersMap: []ekscontrolplanev1.UserMapping{ 203 { 204 UserARN: "arn:aws:iam::000000000000:user/Alice", 205 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 206 UserName: "alice", 207 Groups: []string{"system:masters"}, 208 }, 209 }, 210 }, 211 expectError: false, 212 }, 213 { 214 name: "existing user mapping, add different user mapping", 215 userToMap: ekscontrolplanev1.UserMapping{ 216 UserARN: "arn:aws:iam::000000000000:user/Bob", 217 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 218 UserName: "bob", 219 Groups: []string{"system:masters"}, 220 }, 221 }, 222 expectedUsersMap: []ekscontrolplanev1.UserMapping{ 223 { 224 UserARN: "arn:aws:iam::000000000000:user/Alice", 225 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 226 UserName: "alice", 227 Groups: []string{"system:masters"}, 228 }, 229 }, 230 { 231 UserARN: "arn:aws:iam::000000000000:user/Bob", 232 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 233 UserName: "bob", 234 Groups: []string{"system:masters"}, 235 }, 236 }, 237 }, 238 expectError: false, 239 existingAuthConfigMap: createFakeConfigMap("", existingUserMap), 240 }, 241 { 242 name: "existing user mapping, add same user mapping", 243 userToMap: ekscontrolplanev1.UserMapping{ 244 UserARN: "arn:aws:iam::000000000000:user/Alice", 245 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 246 UserName: "alice", 247 Groups: []string{"system:masters"}, 248 }, 249 }, 250 expectedUsersMap: []ekscontrolplanev1.UserMapping{ 251 { 252 UserARN: "arn:aws:iam::000000000000:user/Alice", 253 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 254 UserName: "alice", 255 Groups: []string{"system:masters"}, 256 }, 257 }, 258 }, 259 expectError: false, 260 existingAuthConfigMap: createFakeConfigMap("", existingUserMap), 261 }, 262 } 263 264 for _, tc := range testCases { 265 t.Run(tc.name, func(t *testing.T) { 266 g := NewGomegaWithT(t) 267 268 var client crclient.Client 269 if tc.existingAuthConfigMap == nil { 270 client = fake.NewClientBuilder().Build() 271 } else { 272 client = fake.NewClientBuilder().WithObjects(tc.existingAuthConfigMap).Build() 273 } 274 backend, err := NewBackend(BackendTypeConfigMap, client) 275 g.Expect(err).To(BeNil()) 276 277 err = backend.MapUser(tc.userToMap) 278 if tc.expectError { 279 g.Expect(err).ToNot(BeNil()) 280 return 281 } 282 283 g.Expect(err).To(BeNil()) 284 285 key := types.NamespacedName{ 286 Name: "aws-auth", 287 Namespace: "kube-system", 288 } 289 290 cm := &corev1.ConfigMap{} 291 292 err = client.Get(context.TODO(), key, cm) 293 g.Expect(err).To(BeNil()) 294 295 g.Expect(cm.Name).To(Equal("aws-auth")) 296 g.Expect(cm.Namespace).To(Equal("kube-system")) 297 g.Expect(cm.Data).ToNot(BeNil()) 298 299 actualUserMappings, userMappingsFound := cm.Data["mapUsers"] 300 if len(tc.expectedUsersMap) == 0 { 301 g.Expect(userMappingsFound).To(BeFalse()) 302 } else { 303 users := []ekscontrolplanev1.UserMapping{} 304 err := yaml.Unmarshal([]byte(actualUserMappings), &users) 305 g.Expect(err).To(BeNil()) 306 g.Expect(len(users)).To(Equal(len(tc.expectedUsersMap))) 307 //TODO: we may need to do a better match 308 bothMatch := cmp.Equal(users, tc.expectedUsersMap) 309 g.Expect(bothMatch).To(BeTrue()) 310 } 311 312 _, roleMappingsFound := cm.Data["mapRoles"] 313 g.Expect(roleMappingsFound).To(BeFalse()) 314 }) 315 } 316 } 317 318 func createFakeConfigMap(roleMappings string, userMappings string) *corev1.ConfigMap { 319 cm := &corev1.ConfigMap{ 320 ObjectMeta: metav1.ObjectMeta{ 321 Name: "aws-auth", 322 Namespace: "kube-system", 323 UID: "1234567", 324 }, 325 Data: make(map[string]string), 326 } 327 328 if roleMappings != "" { 329 cm.Data["mapRoles"] = roleMappings 330 } 331 332 if userMappings != "" { 333 cm.Data["mapUsers"] = userMappings 334 } 335 336 return cm 337 }