sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/services/iamauth/crd_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 "strings" 22 "testing" 23 24 "github.com/google/go-cmp/cmp" 25 . "github.com/onsi/gomega" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 iamauthv1 "sigs.k8s.io/aws-iam-authenticator/pkg/mapper/crd/apis/iamauthenticator/v1alpha1" 29 crclient "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/client/fake" 31 32 ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1" 33 ) 34 35 func TestAddRoleMappingCRD(t *testing.T) { 36 testCases := []struct { 37 name string 38 existingRoleMapping *iamauthv1.IAMIdentityMapping 39 roleToMap ekscontrolplanev1.RoleMapping 40 expectedRoleMapSpecs []iamauthv1.IAMIdentityMappingSpec 41 expectError bool 42 }{ 43 { 44 name: "no existing mappings, add role mapping", 45 roleToMap: ekscontrolplanev1.RoleMapping{ 46 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 47 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 48 UserName: "system:node:{{EC2PrivateDNSName}}", 49 Groups: []string{"system:bootstrappers", "system:nodes"}, 50 }, 51 }, 52 expectedRoleMapSpecs: []iamauthv1.IAMIdentityMappingSpec{ 53 { 54 ARN: "arn:aws:iam::000000000000:role/KubernetesNode", 55 Username: "system:node:{{EC2PrivateDNSName}}", 56 Groups: []string{"system:bootstrappers", "system:nodes"}, 57 }, 58 }, 59 expectError: false, 60 }, 61 { 62 name: "existing mapping, add different role mapping", 63 roleToMap: ekscontrolplanev1.RoleMapping{ 64 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 65 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 66 UserName: "system:node:{{EC2PrivateDNSName}}", 67 Groups: []string{"system:bootstrappers", "system:nodes"}, 68 }, 69 }, 70 existingRoleMapping: createIAMAuthMapping("arn:aws:iam::000000000000:role/KubernetesAdmin", "admin:{{SessionName}}", []string{"system:masters"}), 71 expectedRoleMapSpecs: []iamauthv1.IAMIdentityMappingSpec{ 72 { 73 ARN: "arn:aws:iam::000000000000:role/KubernetesAdmin", 74 Username: "admin:{{SessionName}}", 75 Groups: []string{"system:masters"}, 76 }, 77 { 78 ARN: "arn:aws:iam::000000000000:role/KubernetesNode", 79 Username: "system:node:{{EC2PrivateDNSName}}", 80 Groups: []string{"system:bootstrappers", "system:nodes"}, 81 }, 82 }, 83 expectError: false, 84 }, 85 { 86 name: "existing mapping, add same role mapping", 87 roleToMap: ekscontrolplanev1.RoleMapping{ 88 RoleARN: "arn:aws:iam::000000000000:role/KubernetesNode", 89 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 90 UserName: "system:node:{{EC2PrivateDNSName}}", 91 Groups: []string{"system:bootstrappers", "system:nodes"}, 92 }, 93 }, 94 existingRoleMapping: createIAMAuthMapping("arn:aws:iam::000000000000:role/KubernetesNode", "system:node:{{EC2PrivateDNSName}}", []string{"system:bootstrappers", "system:nodes"}), 95 expectedRoleMapSpecs: []iamauthv1.IAMIdentityMappingSpec{ 96 { 97 ARN: "arn:aws:iam::000000000000:role/KubernetesNode", 98 Username: "system:node:{{EC2PrivateDNSName}}", 99 Groups: []string{"system:bootstrappers", "system:nodes"}, 100 }, 101 }, 102 expectError: false, 103 }, 104 { 105 name: "no existing mapping, add role with not role ARN", 106 roleToMap: ekscontrolplanev1.RoleMapping{ 107 RoleARN: "arn:aws:iam::000000000000:user/Alice", 108 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 109 UserName: "system:node:{{EC2PrivateDNSName}}", 110 Groups: []string{"system:bootstrappers", "system:nodes"}, 111 }, 112 }, 113 expectedRoleMapSpecs: []iamauthv1.IAMIdentityMappingSpec{}, 114 expectError: true, 115 }, 116 } 117 118 for _, tc := range testCases { 119 t.Run(tc.name, func(t *testing.T) { 120 g := NewGomegaWithT(t) 121 122 scheme := runtime.NewScheme() 123 iamauthv1.AddToScheme(scheme) 124 125 var client crclient.Client 126 if tc.existingRoleMapping == nil { 127 client = fake.NewClientBuilder().WithScheme(scheme).Build() 128 } else { 129 client = fake.NewClientBuilder().WithScheme(scheme).WithObjects(tc.existingRoleMapping).Build() 130 } 131 backend, err := NewBackend(BackendTypeCRD, client) 132 g.Expect(err).To(BeNil()) 133 134 err = backend.MapRole(tc.roleToMap) 135 if tc.expectError { 136 g.Expect(err).ToNot(BeNil()) 137 return 138 } 139 140 g.Expect(err).To(BeNil()) 141 142 mappings := &iamauthv1.IAMIdentityMappingList{} 143 err = client.List(context.TODO(), mappings) 144 g.Expect(err).To(BeNil()) 145 146 g.Expect(len(mappings.Items)).To(Equal(len(tc.expectedRoleMapSpecs))) 147 148 for _, actualMapping := range mappings.Items { 149 found := false 150 for _, expectedMappingSpec := range tc.expectedRoleMapSpecs { 151 if cmp.Equal(actualMapping.Spec, expectedMappingSpec) { 152 found = true 153 } 154 } 155 g.Expect(found).To(BeTrue()) 156 g.Expect(actualMapping.Namespace).To(Equal("kube-system")) 157 g.Expect(strings.HasPrefix(actualMapping.Name, "capa-iamauth-")).To(BeTrue()) 158 } 159 }) 160 } 161 } 162 func TestAddUserMappingCRD(t *testing.T) { 163 testCases := []struct { 164 name string 165 existingUserMapping *iamauthv1.IAMIdentityMapping 166 userToMap ekscontrolplanev1.UserMapping 167 expectedUserMapSpecs []iamauthv1.IAMIdentityMappingSpec 168 expectError bool 169 }{ 170 { 171 name: "no existing mappings, add user mapping", 172 userToMap: ekscontrolplanev1.UserMapping{ 173 UserARN: "arn:aws:iam::000000000000:user/Alice", 174 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 175 UserName: "alice", 176 Groups: []string{"system:masters"}, 177 }, 178 }, 179 expectedUserMapSpecs: []iamauthv1.IAMIdentityMappingSpec{ 180 { 181 ARN: "arn:aws:iam::000000000000:user/Alice", 182 Username: "alice", 183 Groups: []string{"system:masters"}, 184 }, 185 }, 186 expectError: false, 187 }, 188 { 189 name: "existing mapping, add different user mapping", 190 userToMap: ekscontrolplanev1.UserMapping{ 191 UserARN: "arn:aws:iam::000000000000:user/Alice", 192 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 193 UserName: "alice", 194 Groups: []string{"system:masters"}, 195 }, 196 }, 197 existingUserMapping: createIAMAuthMapping("arn:aws:iam::000000000000:user/Bob", "bob", []string{"system:masters"}), 198 expectedUserMapSpecs: []iamauthv1.IAMIdentityMappingSpec{ 199 { 200 ARN: "arn:aws:iam::000000000000:user/Bob", 201 Username: "bob", 202 Groups: []string{"system:masters"}, 203 }, 204 { 205 ARN: "arn:aws:iam::000000000000:user/Alice", 206 Username: "alice", 207 Groups: []string{"system:masters"}, 208 }, 209 }, 210 expectError: false, 211 }, 212 { 213 name: "existing mapping, add same user mapping", 214 userToMap: ekscontrolplanev1.UserMapping{ 215 UserARN: "arn:aws:iam::000000000000:user/Alice", 216 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 217 UserName: "alice", 218 Groups: []string{"system:masters"}, 219 }, 220 }, 221 existingUserMapping: createIAMAuthMapping("arn:aws:iam::000000000000:user/Alice", "alice", []string{"system:masters"}), 222 expectedUserMapSpecs: []iamauthv1.IAMIdentityMappingSpec{ 223 { 224 ARN: "arn:aws:iam::000000000000:user/Alice", 225 Username: "alice", 226 Groups: []string{"system:masters"}, 227 }, 228 }, 229 expectError: false, 230 }, 231 { 232 name: "no existing mapping, add role with not role ARN", 233 userToMap: ekscontrolplanev1.UserMapping{ 234 UserARN: "arn:aws:iam::000000000000:role/KubernetesNode", 235 KubernetesMapping: ekscontrolplanev1.KubernetesMapping{ 236 UserName: "system:node:{{EC2PrivateDNSName}}", 237 Groups: []string{"system:masters"}, 238 }, 239 }, 240 expectedUserMapSpecs: []iamauthv1.IAMIdentityMappingSpec{}, 241 expectError: true, 242 }, 243 } 244 245 for _, tc := range testCases { 246 t.Run(tc.name, func(t *testing.T) { 247 g := NewGomegaWithT(t) 248 249 scheme := runtime.NewScheme() 250 iamauthv1.AddToScheme(scheme) 251 252 var client crclient.Client 253 if tc.existingUserMapping == nil { 254 client = fake.NewClientBuilder().WithScheme(scheme).Build() 255 } else { 256 client = fake.NewClientBuilder().WithScheme(scheme).WithObjects(tc.existingUserMapping).Build() 257 } 258 backend, err := NewBackend(BackendTypeCRD, client) 259 g.Expect(err).To(BeNil()) 260 261 err = backend.MapUser(tc.userToMap) 262 if tc.expectError { 263 g.Expect(err).ToNot(BeNil()) 264 return 265 } 266 267 g.Expect(err).To(BeNil()) 268 269 mappings := &iamauthv1.IAMIdentityMappingList{} 270 err = client.List(context.TODO(), mappings) 271 g.Expect(err).To(BeNil()) 272 273 g.Expect(len(mappings.Items)).To(Equal(len(tc.expectedUserMapSpecs))) 274 275 for _, actualMapping := range mappings.Items { 276 found := false 277 for _, expectedMappingSpec := range tc.expectedUserMapSpecs { 278 if cmp.Equal(actualMapping.Spec, expectedMappingSpec) { 279 found = true 280 } 281 } 282 g.Expect(found).To(BeTrue()) 283 g.Expect(actualMapping.Namespace).To(Equal("kube-system")) 284 g.Expect(strings.HasPrefix(actualMapping.Name, "capa-iamauth-")).To(BeTrue()) 285 } 286 }) 287 } 288 } 289 290 func createIAMAuthMapping(arn string, username string, groups []string) *iamauthv1.IAMIdentityMapping { 291 return &iamauthv1.IAMIdentityMapping{ 292 ObjectMeta: metav1.ObjectMeta{ 293 Name: "capa-iamauth-abcd1234", 294 Namespace: "kube-system", 295 UID: "1234567890", 296 }, 297 Spec: iamauthv1.IAMIdentityMappingSpec{ 298 ARN: arn, 299 Username: username, 300 Groups: groups, 301 }, 302 } 303 }