github.com/verrazzano/verrazzano@v1.7.1/cluster-operator/controllers/quickcreate/oke/oke_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 oke
     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  	vzstring "github.com/verrazzano/verrazzano/pkg/string"
    13  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    14  	"k8s.io/apimachinery/pkg/runtime"
    15  	ctrl "sigs.k8s.io/controller-runtime"
    16  )
    17  
    18  const (
    19  	finalizerKey = "verrazzano.io/oci-oke-cluster"
    20  )
    21  
    22  var (
    23  	//go:embed template/cluster/cluster.goyaml
    24  	clusterTemplate []byte
    25  	//go:embed template/nodes/nodes.goyaml
    26  	nodesTemplate []byte
    27  )
    28  
    29  type ClusterReconciler struct {
    30  	*controller.Base
    31  	Scheme            *runtime.Scheme
    32  	CredentialsLoader oci.CredentialsLoader
    33  	OCIClientGetter   func(credentials *oci.Credentials) (oci.Client, error)
    34  }
    35  
    36  func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    37  	q := &vmcv1alpha1.OKEQuickCreate{}
    38  	err := r.Get(ctx, req.NamespacedName, q)
    39  	// if cluster not found, no work to be done
    40  	if apierrors.IsNotFound(err) {
    41  		return controller.RequeueDelay(), nil
    42  	}
    43  	if err != nil {
    44  		return controller.RequeueDelay(), err
    45  	}
    46  	if err := r.SetNewResourceLogger(q); err != nil {
    47  		return controller.RequeueDelay(), err
    48  	}
    49  	return r.reconcile(ctx, q)
    50  }
    51  
    52  func (r *ClusterReconciler) reconcile(ctx context.Context, q *vmcv1alpha1.OKEQuickCreate) (ctrl.Result, error) {
    53  	// If quick create is completed, or being deleted, clean up the quick create
    54  	if !q.GetDeletionTimestamp().IsZero() || q.Status.Phase == vmcv1alpha1.QuickCreatePhaseComplete {
    55  		return ctrl.Result{}, r.Cleanup(ctx, q, finalizerKey)
    56  	}
    57  	// Add any finalizers if they are not present
    58  	if isMissingFinalizer(q) {
    59  		return r.SetFinalizers(ctx, q, finalizerKey)
    60  	}
    61  	return r.syncCluster(ctx, q)
    62  }
    63  
    64  func (r *ClusterReconciler) syncCluster(ctx context.Context, q *vmcv1alpha1.OKEQuickCreate) (ctrl.Result, error) {
    65  	props, err := NewProperties(ctx, r.Client, r.CredentialsLoader, r.OCIClientGetter, q)
    66  	if err != nil {
    67  		return controller.RequeueDelay(), err
    68  	}
    69  	// If provisioning has not successfully started, attempt to create the OKE control plane
    70  	if shouldProvision(q) {
    71  		if err := controller.ApplyTemplates(r.Client, props, q.Namespace, clusterTemplate); err != nil {
    72  			return controller.RequeueDelay(), err
    73  		}
    74  		q.Status = vmcv1alpha1.OKEQuickCreateStatus{
    75  			Phase: vmcv1alpha1.QuickCreatePhaseProvisioning,
    76  		}
    77  		r.Log.Oncef("provisioning OKE cluster: %s/%s", q.Namespace, q.Name)
    78  		return r.UpdateStatus(ctx, q)
    79  	}
    80  	// If OCI Network is loaded, create the nodes and update phase to completed
    81  	if props.HasOCINetwork() {
    82  		if err := controller.ApplyTemplates(r.Client, props, q.Namespace, nodesTemplate); err != nil {
    83  			return controller.RequeueDelay(), err
    84  		}
    85  		q.Status.Phase = vmcv1alpha1.QuickCreatePhaseComplete
    86  		r.Log.Oncef("completed provisioning OKE cluster: %s/%s", q.Namespace, q.Name)
    87  		return r.UpdateStatus(ctx, q)
    88  	}
    89  	r.Log.Progressf("waiting for OKE cluster infrastructure: %s/%s", q.Namespace, q.Name)
    90  	// Quick Create is not complete yet, requeue
    91  	return controller.RequeueDelay(), nil
    92  }
    93  
    94  func isMissingFinalizer(q *vmcv1alpha1.OKEQuickCreate) bool {
    95  	return !vzstring.SliceContainsString(q.GetFinalizers(), finalizerKey)
    96  }
    97  
    98  func shouldProvision(q *vmcv1alpha1.OKEQuickCreate) bool {
    99  	return q.Status.Phase == ""
   100  }
   101  
   102  // SetupWithManager creates a new controller and adds it to the manager
   103  func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
   104  	return ctrl.NewControllerManagedBy(mgr).
   105  		For(&vmcv1alpha1.OKEQuickCreate{}).
   106  		Complete(r)
   107  }