sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/services/iamauth/crd.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 "fmt" 22 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 kerrors "k8s.io/apimachinery/pkg/util/errors" 25 iamauthv1 "sigs.k8s.io/aws-iam-authenticator/pkg/mapper/crd/apis/iamauthenticator/v1alpha1" 26 crclient "sigs.k8s.io/controller-runtime/pkg/client" 27 28 ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1" 29 ) 30 31 type crdBackend struct { 32 client crclient.Client 33 } 34 35 func (b *crdBackend) MapRole(mapping ekscontrolplanev1.RoleMapping) error { 36 ctx := context.TODO() 37 38 if errs := mapping.Validate(); errs != nil { 39 return kerrors.NewAggregate(errs) 40 } 41 42 mappingList := iamauthv1.IAMIdentityMappingList{} 43 44 if err := b.client.List(ctx, &mappingList); err != nil { 45 return fmt.Errorf("getting list of mappings: %w", err) 46 } 47 48 for _, existingMapping := range mappingList.Items { 49 existing := existingMapping 50 if roleMappingMatchesIAMMap(mapping, &existing) { 51 // We already have a mapping so do nothing 52 return nil 53 } 54 } 55 56 iamMapping := &iamauthv1.IAMIdentityMapping{ 57 ObjectMeta: metav1.ObjectMeta{ 58 Namespace: metav1.NamespaceSystem, 59 GenerateName: "capa-iamauth-", 60 }, 61 Spec: iamauthv1.IAMIdentityMappingSpec{ 62 ARN: mapping.RoleARN, 63 Username: mapping.UserName, 64 Groups: mapping.Groups, 65 }, 66 } 67 68 return b.client.Create(ctx, iamMapping) 69 } 70 71 func (b *crdBackend) MapUser(mapping ekscontrolplanev1.UserMapping) error { 72 ctx := context.TODO() 73 74 if errs := mapping.Validate(); errs != nil { 75 return kerrors.NewAggregate(errs) 76 } 77 78 mappingList := iamauthv1.IAMIdentityMappingList{} 79 80 if err := b.client.List(ctx, &mappingList); err != nil { 81 return fmt.Errorf("getting list of mappings: %w", err) 82 } 83 84 for _, existingMapping := range mappingList.Items { 85 existing := existingMapping 86 if userMappingMatchesIAMMap(mapping, &existing) { 87 // We already have a mapping so do nothing 88 return nil 89 } 90 } 91 92 iamMapping := &iamauthv1.IAMIdentityMapping{ 93 ObjectMeta: metav1.ObjectMeta{ 94 Namespace: metav1.NamespaceSystem, 95 GenerateName: "capa-iamauth-", 96 }, 97 Spec: iamauthv1.IAMIdentityMappingSpec{ 98 ARN: mapping.UserARN, 99 Username: mapping.UserName, 100 Groups: mapping.Groups, 101 }, 102 } 103 104 return b.client.Create(ctx, iamMapping) 105 } 106 107 func roleMappingMatchesIAMMap(mapping ekscontrolplanev1.RoleMapping, iamMapping *iamauthv1.IAMIdentityMapping) bool { 108 if mapping.RoleARN != iamMapping.Spec.ARN { 109 return false 110 } 111 112 if mapping.UserName != iamMapping.Spec.Username { 113 return false 114 } 115 116 if len(mapping.Groups) != len(iamMapping.Spec.Groups) { 117 return false 118 } 119 120 for _, mappingGroup := range mapping.Groups { 121 found := false 122 for _, iamGroup := range iamMapping.Spec.Groups { 123 if iamGroup == mappingGroup { 124 found = true 125 } 126 } 127 if !found { 128 return false 129 } 130 } 131 132 return true 133 } 134 135 func userMappingMatchesIAMMap(mapping ekscontrolplanev1.UserMapping, iamMapping *iamauthv1.IAMIdentityMapping) bool { 136 if mapping.UserARN != iamMapping.Spec.ARN { 137 return false 138 } 139 140 if mapping.UserName != iamMapping.Spec.Username { 141 return false 142 } 143 144 if len(mapping.Groups) != len(iamMapping.Spec.Groups) { 145 return false 146 } 147 148 for _, mappingGroup := range mapping.Groups { 149 found := false 150 for _, iamGroup := range iamMapping.Spec.Groups { 151 if iamGroup == mappingGroup { 152 found = true 153 } 154 } 155 if !found { 156 return false 157 } 158 } 159 160 return true 161 }