diff --git a/controllers/ocimachine_controller.go b/controllers/ocimachine_controller.go index 87e4d776..bbd8e9ad 100644 --- a/controllers/ocimachine_controller.go +++ b/controllers/ocimachine_controller.go @@ -112,7 +112,16 @@ func (r *OCIMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request) } var clusterAccessor scope.OCIClusterAccessor - if err := r.Client.Get(ctx, ociClusterName, ociCluster); err != nil { + if cluster.Spec.InfrastructureRef.Kind == "OCICluster" { + if err := r.Client.Get(ctx, ociClusterName, ociCluster); err != nil { + logger.Info("Cluster is not available yet") + r.Recorder.Eventf(ociMachine, corev1.EventTypeWarning, "ClusterNotAvailable", "Cluster is not available yet") + return ctrl.Result{}, nil + } + clusterAccessor = scope.OCISelfManagedCluster{ + OCICluster: ociCluster, + } + } else if cluster.Spec.InfrastructureRef.Kind == "OCIManagedCluster" { // check for oci managed cluster ociManagedCluster := &infrastructurev1beta2.OCIManagedCluster{} ociManagedClusterName := client.ObjectKey{ @@ -120,17 +129,14 @@ func (r *OCIMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request) Name: cluster.Spec.InfrastructureRef.Name, } if err := r.Client.Get(ctx, ociManagedClusterName, ociManagedCluster); err != nil { - logger.Info("Cluster is not available yet") - r.Recorder.Eventf(ociMachine, corev1.EventTypeWarning, "ClusterNotAvailable", "Cluster is not available yet") - return ctrl.Result{}, nil + } clusterAccessor = scope.OCIManagedCluster{ OCIManagedCluster: ociManagedCluster, } } else { - clusterAccessor = scope.OCISelfManagedCluster{ - OCICluster: ociCluster, - } + r.Recorder.Eventf(ociMachine, corev1.EventTypeWarning, "InfrastructureClusterTypeNotSupported", fmt.Sprintf("Infrastructure Cluster Type %s is not supported", cluster.Spec.InfrastructureRef.Kind)) + return ctrl.Result{}, errors.New(fmt.Sprintf("Infrastructure Cluster Type %s is not supported", cluster.Spec.InfrastructureRef.Kind)) } _, _, clients, err := cloudutil.InitClientsAndRegion(ctx, r.Client, r.Region, clusterAccessor, r.ClientProvider) @@ -189,6 +195,10 @@ func (r *OCIMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma &infrastructurev1beta2.OCICluster{}, handler.EnqueueRequestsFromMapFunc(r.OCIClusterToOCIMachines()), ). + Watches( + &infrastructurev1beta2.OCIManagedCluster{}, + handler.EnqueueRequestsFromMapFunc(r.OCIManagedClusterToOCIMachines()), + ). Watches( &clusterv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc), @@ -242,6 +252,44 @@ func (r *OCIMachineReconciler) OCIClusterToOCIMachines() handler.MapFunc { } } +func (r *OCIMachineReconciler) OCIManagedClusterToOCIMachines() handler.MapFunc { + return func(ctx context.Context, o client.Object) []ctrl.Request { + log := ctrl.LoggerFrom(ctx) + result := []ctrl.Request{} + + c, ok := o.(*infrastructurev1beta2.OCIManagedCluster) + if !ok { + log.Error(errors.Errorf("expected a OCICluster but got a %T", o), "failed to get OCIMachine for OCICluster") + return nil + } + + cluster, err := util.GetOwnerCluster(ctx, r.Client, c.ObjectMeta) + switch { + case apierrors.IsNotFound(err) || cluster == nil: + return result + case err != nil: + log.Error(err, "failed to get owning cluster") + return result + } + + labels := map[string]string{clusterv1.ClusterNameLabel: cluster.Name} + machineList := &clusterv1.MachineList{} + if err := r.List(ctx, machineList, client.InNamespace(c.Namespace), client.MatchingLabels(labels)); err != nil { + log.Error(err, "failed to list Machines") + return nil + } + for _, m := range machineList.Items { + if m.Spec.InfrastructureRef.Name == "" { + continue + } + name := client.ObjectKey{Namespace: m.Namespace, Name: m.Spec.InfrastructureRef.Name} + result = append(result, ctrl.Request{NamespacedName: name}) + } + + return result + } +} + func (r *OCIMachineReconciler) reconcileNormal(ctx context.Context, logger logr.Logger, machineScope *scope.MachineScope) (ctrl.Result, error) { controllerutil.AddFinalizer(machineScope.OCIMachine, infrastructurev1beta2.MachineFinalizer) machine := machineScope.OCIMachine diff --git a/controllers/ocimachine_controller_test.go b/controllers/ocimachine_controller_test.go index 988b839d..e3eb343b 100644 --- a/controllers/ocimachine_controller_test.go +++ b/controllers/ocimachine_controller_test.go @@ -954,6 +954,7 @@ func getOciMachineWithNoOwner() *infrastructurev1beta2.OCIMachine { func getCluster() *clusterv1.Cluster { infraRef := corev1.ObjectReference{ Name: "oci-cluster", + Kind: "OCICluster", } return &clusterv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ diff --git a/exp/controllers/ocimachinepool_controller.go b/exp/controllers/ocimachinepool_controller.go index 5f1422a0..5848b5af 100644 --- a/exp/controllers/ocimachinepool_controller.go +++ b/exp/controllers/ocimachinepool_controller.go @@ -47,6 +47,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -113,15 +114,23 @@ func (r *OCIMachinePoolReconciler) Reconcile(ctx context.Context, req ctrl.Reque logger.Info("OCIMachinePool or linked Cluster is marked as paused. Won't reconcile") return ctrl.Result{}, nil } - - ociCluster := &infrastructurev1beta2.OCICluster{} - ociClusterName := client.ObjectKey{ - Namespace: cluster.Namespace, - Name: cluster.Name, - } - var clusterAccessor scope.OCIClusterAccessor - if err := r.Client.Get(ctx, ociClusterName, ociCluster); err != nil { + if cluster.Spec.InfrastructureRef.Kind == "OCICluster" { + ociCluster := &infrastructurev1beta2.OCICluster{} + ociClusterName := client.ObjectKey{ + Namespace: cluster.Namespace, + Name: cluster.Spec.InfrastructureRef.Name, + } + if err := r.Client.Get(ctx, ociClusterName, ociCluster); err != nil { + logger.Info("Cluster is not available yet") + r.Recorder.Eventf(ociMachinePool, corev1.EventTypeWarning, "ClusterNotAvailable", "Cluster is not available yet") + logger.V(2).Info("OCICluster is not available yet") + return ctrl.Result{}, nil + } + clusterAccessor = scope.OCISelfManagedCluster{ + OCICluster: ociCluster, + } + } else if cluster.Spec.InfrastructureRef.Kind == "OCIManagedCluster" { ociManagedCluster := &infrastructurev1beta2.OCIManagedCluster{} ociManagedClusterName := client.ObjectKey{ Namespace: cluster.Namespace, @@ -130,16 +139,15 @@ func (r *OCIMachinePoolReconciler) Reconcile(ctx context.Context, req ctrl.Reque if err := r.Client.Get(ctx, ociManagedClusterName, ociManagedCluster); err != nil { logger.Info("Cluster is not available yet") r.Recorder.Eventf(ociMachinePool, corev1.EventTypeWarning, "ClusterNotAvailable", "Cluster is not available yet") - logger.V(2).Info("OCICluster is not available yet") + logger.V(2).Info("OCIManagedCluster is not available yet") return ctrl.Result{}, nil } clusterAccessor = scope.OCIManagedCluster{ OCIManagedCluster: ociManagedCluster, } } else { - clusterAccessor = scope.OCISelfManagedCluster{ - OCICluster: ociCluster, - } + r.Recorder.Eventf(ociMachinePool, corev1.EventTypeWarning, "InfrastructureClusterTypeNotSupported", fmt.Sprintf("Infrastructure Cluster Type %s is not supported", cluster.Spec.InfrastructureRef.Kind)) + return ctrl.Result{}, errors.New(fmt.Sprintf("Infrastructure Cluster Type %s is not supported", cluster.Spec.InfrastructureRef.Kind)) } _, _, clients, err := cloudutil.InitClientsAndRegion(ctx, r.Client, r.Region, clusterAccessor, r.ClientProvider) @@ -184,15 +192,24 @@ func (r *OCIMachinePoolReconciler) SetupWithManager(ctx context.Context, mgr ctr if err != nil { return errors.Wrapf(err, "failed to create mapper for Cluster to OCIMachinePool") } + gvk, err := apiutil.GVKForObject(new(infrav2exp.OCIMachinePool), mgr.GetScheme()) + if err != nil { + return errors.Wrapf(err, "failed to find GVK for OCIMachinePool") + } + managedClusterToMachinePoolMap := managedClusterToManagedMachinePoolMapFunc(r.Client, gvk, logger) + err = ctrl.NewControllerManagedBy(mgr). WithOptions(options). For(&infrav2exp.OCIMachinePool{}). - WithEventFilter(predicates.ResourceNotPaused(ctrl.LoggerFrom(ctx))). Watches( &expclusterv1.MachinePool{}, handler.EnqueueRequestsFromMapFunc(machinePoolToInfrastructureMapFunc(infrav2exp. GroupVersion.WithKind(scope.OCIMachinePoolKind), logger)), ). + Watches( + &infrastructurev1beta2.OCIManagedCluster{}, + handler.EnqueueRequestsFromMapFunc(managedClusterToMachinePoolMap), + ). Watches( &clusterv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc), @@ -200,6 +217,7 @@ func (r *OCIMachinePoolReconciler) SetupWithManager(ctx context.Context, mgr ctr predicates.ClusterUnpausedAndInfrastructureReady(ctrl.LoggerFrom(ctx)), ), ). + WithEventFilter(predicates.ResourceNotPaused(ctrl.LoggerFrom(ctx))). Complete(r) if err != nil { diff --git a/exp/controllers/ocimanaged_machinepool_controller.go b/exp/controllers/ocimanaged_machinepool_controller.go index e8a1fe41..09fbcfb1 100644 --- a/exp/controllers/ocimanaged_machinepool_controller.go +++ b/exp/controllers/ocimanaged_machinepool_controller.go @@ -117,7 +117,7 @@ func (r *OCIManagedMachinePoolReconciler) Reconcile(ctx context.Context, req ctr ociManagedCluster := &infrastructurev1beta2.OCIManagedCluster{} ociClusterName := client.ObjectKey{ Namespace: cluster.Namespace, - Name: cluster.Name, + Name: cluster.Spec.InfrastructureRef.Name, } if err := r.Client.Get(ctx, ociClusterName, ociManagedCluster); err != nil { @@ -216,7 +216,7 @@ func managedClusterToManagedMachinePoolMapFunc(c client.Client, gvk schema.Group return func(ctx context.Context, o client.Object) []reconcile.Request { ociCluster, ok := o.(*infrastructurev1beta2.OCIManagedCluster) if !ok { - panic(fmt.Sprintf("Expected a OCIManagedControlPlane but got a %T", o)) + panic(fmt.Sprintf("Expected a OCIManagedCluster but got a %T", o)) } if !ociCluster.ObjectMeta.DeletionTimestamp.IsZero() { @@ -225,7 +225,7 @@ func managedClusterToManagedMachinePoolMapFunc(c client.Client, gvk schema.Group cluster, err := util.GetOwnerCluster(ctx, c, ociCluster.ObjectMeta) if err != nil { - log.Error(err, "couldn't get OCI control plane owner ObjectKey") + log.Error(err, "couldn't get OCIManagedCluster owner ObjectKey") return nil } if cluster == nil { diff --git a/exp/controllers/ocimanaged_machinepool_controller_test.go b/exp/controllers/ocimanaged_machinepool_controller_test.go index ad78672e..85de3534 100644 --- a/exp/controllers/ocimanaged_machinepool_controller_test.go +++ b/exp/controllers/ocimanaged_machinepool_controller_test.go @@ -802,6 +802,7 @@ func getMachinePool() *expclusterv1.MachinePool { func getCluster() *clusterv1.Cluster { infraRef := corev1.ObjectReference{ Name: "oci-cluster", + Kind: "OCICluster", } return &clusterv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ diff --git a/exp/controllers/ocivirtual_machinepool_controller.go b/exp/controllers/ocivirtual_machinepool_controller.go index 16089f4a..cf0c61a2 100644 --- a/exp/controllers/ocivirtual_machinepool_controller.go +++ b/exp/controllers/ocivirtual_machinepool_controller.go @@ -116,7 +116,7 @@ func (r *OCIVirtualMachinePoolReconciler) Reconcile(ctx context.Context, req ctr ociManagedCluster := &infrastructurev1beta2.OCIManagedCluster{} ociClusterName := client.ObjectKey{ Namespace: cluster.Namespace, - Name: cluster.Name, + Name: cluster.Spec.InfrastructureRef.Name, } if err := r.Client.Get(ctx, ociClusterName, ociManagedCluster); err != nil { diff --git a/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed-virtual/cluster.yaml b/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed-virtual/cluster.yaml index 50f9c4ca..5dd8d864 100644 --- a/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed-virtual/cluster.yaml +++ b/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed-virtual/cluster.yaml @@ -9,7 +9,7 @@ spec: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta2 kind: OCIManagedCluster - name: "${CLUSTER_NAME}" + name: "${CLUSTER_NAME}-virtual" namespace: "${NAMESPACE}" controlPlaneRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta2 @@ -22,7 +22,7 @@ kind: OCIManagedCluster metadata: labels: cluster.x-k8s.io/cluster-name: "${CLUSTER_NAME}" - name: "${CLUSTER_NAME}" + name: "${CLUSTER_NAME}-virtual" spec: compartmentId: "${OCI_COMPARTMENT_ID}" identityRef: diff --git a/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed/cluster.yaml b/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed/cluster.yaml index c5370726..f38dcbb4 100644 --- a/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed/cluster.yaml +++ b/test/e2e/data/infrastructure-oci/v1beta2/cluster-template-managed/cluster.yaml @@ -9,7 +9,7 @@ spec: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta2 kind: OCIManagedCluster - name: "${CLUSTER_NAME}" + name: "${CLUSTER_NAME}-managed" namespace: "${NAMESPACE}" controlPlaneRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta2 @@ -22,7 +22,7 @@ kind: OCIManagedCluster metadata: labels: cluster.x-k8s.io/cluster-name: "${CLUSTER_NAME}" - name: "${CLUSTER_NAME}" + name: "${CLUSTER_NAME}-managed" spec: compartmentId: "${OCI_COMPARTMENT_ID}" ---