sigs.k8s.io/cluster-api-provider-aws@v1.5.5/exp/controlleridentitycreator/awscontrolleridentity_controller.go (about) 1 /* 2 Copyright 2021 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 controlleridentitycreator 18 19 import ( 20 "context" 21 "fmt" 22 23 "github.com/go-logr/logr" 24 apierrors "k8s.io/apimachinery/pkg/api/errors" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/types" 27 ctrl "sigs.k8s.io/controller-runtime" 28 "sigs.k8s.io/controller-runtime/pkg/client" 29 "sigs.k8s.io/controller-runtime/pkg/controller" 30 "sigs.k8s.io/controller-runtime/pkg/handler" 31 "sigs.k8s.io/controller-runtime/pkg/reconcile" 32 "sigs.k8s.io/controller-runtime/pkg/source" 33 34 infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" 35 ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1" 36 "sigs.k8s.io/cluster-api-provider-aws/feature" 37 "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/scope" 38 "sigs.k8s.io/cluster-api/util/predicates" 39 ) 40 41 // AWSControllerIdentityReconciler reconciles a AWSClusterControllerIdentity object. 42 type AWSControllerIdentityReconciler struct { 43 client.Client 44 Log logr.Logger 45 Endpoints []scope.ServiceEndpoint 46 WatchFilterValue string 47 } 48 49 // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclustercontrolleridentities,verbs=get;list;watch;create 50 51 func (r *AWSControllerIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 52 log := ctrl.LoggerFrom(ctx) 53 54 var identityRef *infrav1.AWSIdentityReference 55 56 // Fetch the AWSCluster instance 57 awsCluster := &infrav1.AWSCluster{} 58 clusterFound := true 59 err := r.Get(ctx, req.NamespacedName, awsCluster) 60 if err != nil { 61 if !apierrors.IsNotFound(err) { 62 return reconcile.Result{}, err 63 } 64 log.V(4).Info("AWSCluster not found, trying AWSManagedControlPlane") 65 clusterFound = false 66 } else { 67 log.V(4).Info("Found identityRef on AWSCluster") 68 identityRef = awsCluster.Spec.IdentityRef 69 } 70 71 // If AWSCluster is not found, check if AWSManagedControlPlane is used. 72 if !clusterFound && feature.Gates.Enabled(feature.EKS) { 73 awsControlPlane := &ekscontrolplanev1.AWSManagedControlPlane{} 74 if err := r.Client.Get(ctx, req.NamespacedName, awsControlPlane); err != nil { 75 if apierrors.IsNotFound(err) { 76 log.V(4).Info("AWSManagedMachinePool not found, no identityRef so no action taken") 77 return ctrl.Result{}, nil 78 } 79 return reconcile.Result{}, err 80 } 81 log.V(4).Info("Found identityRef on AWSManagedControlPlane") 82 identityRef = awsControlPlane.Spec.IdentityRef 83 } 84 85 log = log.WithValues("cluster", req.Name) 86 if identityRef == nil { 87 log.Info("IdentityRef is nil, skipping reconciliation") 88 return ctrl.Result{Requeue: true}, nil 89 } 90 91 // If identity type is not AWSClusterControllerIdentity, then no need to create AWSClusterControllerIdentity singleton. 92 if identityRef.Kind == infrav1.ClusterRoleIdentityKind || 93 identityRef.Kind == infrav1.ClusterStaticIdentityKind { 94 log.V(4).Info("Cluster does not use AWSClusterControllerIdentity as identityRef, skipping new instance creation") 95 return ctrl.Result{}, nil 96 } 97 98 // Fetch the AWSClusterControllerIdentity instance 99 controllerIdentity := &infrav1.AWSClusterControllerIdentity{} 100 err = r.Get(ctx, types.NamespacedName{Name: infrav1.AWSClusterControllerIdentityName}, controllerIdentity) 101 // If AWSClusterControllerIdentity instance already exists, then do not update it. 102 if err == nil { 103 return ctrl.Result{}, nil 104 } 105 if apierrors.IsNotFound(err) { 106 log.Info("AWSClusterControllerIdentity instance not found, creating a new instance") 107 // Fetch the AWSClusterControllerIdentity instance 108 controllerIdentity = &infrav1.AWSClusterControllerIdentity{ 109 TypeMeta: metav1.TypeMeta{ 110 APIVersion: infrav1.GroupVersion.String(), 111 Kind: string(infrav1.ControllerIdentityKind), 112 }, 113 ObjectMeta: metav1.ObjectMeta{ 114 Name: infrav1.AWSClusterControllerIdentityName, 115 }, 116 Spec: infrav1.AWSClusterControllerIdentitySpec{ 117 AWSClusterIdentitySpec: infrav1.AWSClusterIdentitySpec{ 118 AllowedNamespaces: &infrav1.AllowedNamespaces{}, 119 }, 120 }, 121 } 122 err := r.Create(ctx, controllerIdentity) 123 if err != nil { 124 if apierrors.IsAlreadyExists(err) { 125 return reconcile.Result{}, nil 126 } 127 return reconcile.Result{}, err 128 } 129 return reconcile.Result{}, nil 130 } 131 return reconcile.Result{}, err 132 } 133 134 func (r *AWSControllerIdentityReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error { 135 controller := ctrl.NewControllerManagedBy(mgr). 136 For(&infrav1.AWSCluster{}). 137 WithOptions(options). 138 WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue)) 139 140 if feature.Gates.Enabled(feature.EKS) { 141 controller.Watches( 142 &source.Kind{Type: &ekscontrolplanev1.AWSManagedControlPlane{}}, 143 handler.EnqueueRequestsFromMapFunc(r.managedControlPlaneMap), 144 ) 145 } 146 147 return controller.Complete(r) 148 } 149 150 func (r *AWSControllerIdentityReconciler) managedControlPlaneMap(o client.Object) []ctrl.Request { 151 managedControlPlane, ok := o.(*ekscontrolplanev1.AWSManagedControlPlane) 152 if !ok { 153 panic(fmt.Sprintf("Expected a managedControlPlane but got a %T", o)) 154 } 155 156 return []ctrl.Request{ 157 { 158 NamespacedName: types.NamespacedName{ 159 Name: managedControlPlane.Name, 160 Namespace: managedControlPlane.Namespace, 161 }, 162 }, 163 } 164 }