github.com/verrazzano/verrazzano@v1.7.0/cluster-operator/controllers/quickcreate/ociocne/ociocne_controller.go (about) 1 // Copyright (c) 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package ociocne 5 6 import ( 7 "context" 8 _ "embed" 9 vmcv1alpha1 "github.com/verrazzano/verrazzano/cluster-operator/apis/clusters/v1alpha1" 10 "github.com/verrazzano/verrazzano/cluster-operator/controllers/quickcreate/controller" 11 "github.com/verrazzano/verrazzano/cluster-operator/controllers/quickcreate/controller/oci" 12 "github.com/verrazzano/verrazzano/cluster-operator/internal/capi" 13 "github.com/verrazzano/verrazzano/pkg/k8s/node" 14 apierrors "k8s.io/apimachinery/pkg/api/errors" 15 "k8s.io/apimachinery/pkg/runtime" 16 "k8s.io/apimachinery/pkg/types" 17 ctrl "sigs.k8s.io/controller-runtime" 18 ) 19 20 const ( 21 finalizerKey = "verrazzano.io/oci-ocne-cluster" 22 ) 23 24 var ( 25 //go:embed template/addons/addons.goyaml 26 addonsTemplate []byte 27 //go:embed template/cluster/cluster.goyaml 28 clusterTemplate []byte 29 //go:embed template/cluster/nodes.goyaml 30 nodesTemplate []byte 31 //go:embed template/cluster/ocne.goyaml 32 ocneTemplate []byte 33 ) 34 35 type ClusterReconciler struct { 36 *controller.Base 37 Scheme *runtime.Scheme 38 CredentialsLoader oci.CredentialsLoader 39 OCIClientGetter func(credentials *oci.Credentials) (oci.Client, error) 40 } 41 42 func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 43 q := &vmcv1alpha1.OCNEOCIQuickCreate{} 44 err := r.Get(ctx, req.NamespacedName, q) 45 // if cluster not found, no work to be done 46 if apierrors.IsNotFound(err) { 47 return ctrl.Result{}, nil 48 } 49 if err != nil { 50 return controller.RequeueDelay(), err 51 } 52 if err := r.SetNewResourceLogger(q); err != nil { 53 return controller.RequeueDelay(), err 54 } 55 return r.reconcile(ctx, q) 56 } 57 58 func (r *ClusterReconciler) reconcile(ctx context.Context, q *vmcv1alpha1.OCNEOCIQuickCreate) (ctrl.Result, error) { 59 // If quick create is completed, or being deleted, clean up the quick create 60 if !q.GetDeletionTimestamp().IsZero() || q.Status.Phase == vmcv1alpha1.QuickCreatePhaseComplete { 61 return ctrl.Result{}, r.Cleanup(ctx, q, finalizerKey) 62 } 63 // Add any finalizers if they are not present 64 if isMissingFinalizer(q) { 65 return r.SetFinalizers(ctx, q, finalizerKey) 66 } 67 return r.syncCluster(ctx, q) 68 } 69 70 func (r *ClusterReconciler) syncCluster(ctx context.Context, q *vmcv1alpha1.OCNEOCIQuickCreate) (ctrl.Result, error) { 71 ocne, err := NewProperties(ctx, r.Client, r.CredentialsLoader, r.OCIClientGetter, q) 72 if err != nil { 73 return controller.RequeueDelay(), err 74 } 75 // If provisioning has not successfully started, attempt to provisioning the cluster 76 if shouldProvision(q) { 77 if err := controller.ApplyTemplates(r.Client, ocne, q.Namespace, clusterTemplate, nodesTemplate, ocneTemplate); err != nil { 78 return controller.RequeueDelay(), err 79 } 80 q.Status = vmcv1alpha1.OCNEOCIQuickCreateStatus{ 81 Phase: vmcv1alpha1.QuickCreatePhaseProvisioning, 82 } 83 r.Log.Oncef("provisioning OCNE OCI cluster: %s/%s", q.Namespace, q.Name) 84 return r.UpdateStatus(ctx, q) 85 } 86 // If OCI Network is loaded, update the quick create to completed phase 87 if ocne.HasOCINetwork() { 88 if err := controller.ApplyTemplates(r.Client, ocne, q.Namespace, addonsTemplate); err != nil { 89 return controller.RequeueDelay(), err 90 } 91 // If the cluster only has control plane nodes, set them for scheduling 92 if ocne.IsControlPlaneOnly() { 93 if err := r.setControlPlaneSchedulable(ctx, q); err != nil { 94 return controller.RequeueDelay(), nil 95 } 96 } 97 r.Log.Oncef("completed provisioning OCNE OCI cluster: %s/%s", q.Namespace, q.Name) 98 q.Status.Phase = vmcv1alpha1.QuickCreatePhaseComplete 99 return r.UpdateStatus(ctx, q) 100 } 101 102 r.Log.Progressf("waiting for OCNE OCI cluster infrastructure: %s/%s", q.Namespace, q.Name) 103 // Quick Create is not complete yet, requeue 104 return controller.RequeueDelay(), nil 105 } 106 107 func (r *ClusterReconciler) setControlPlaneSchedulable(ctx context.Context, q *vmcv1alpha1.OCNEOCIQuickCreate) error { 108 cli, err := capi.GetClusterClient(ctx, r.Client, types.NamespacedName{ 109 Namespace: q.Namespace, 110 Name: q.Name, 111 }, r.Scheme) 112 if err != nil { 113 return err 114 } 115 return node.SetControlPlaneScheduling(ctx, cli) 116 } 117 118 // SetupWithManager creates a new controller and adds it to the manager 119 func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { 120 return ctrl.NewControllerManagedBy(mgr). 121 For(&vmcv1alpha1.OCNEOCIQuickCreate{}). 122 Complete(r) 123 }