github.com/verrazzano/verrazzano@v1.7.1/platform-operator/controllers/module/component-handler/installupdate/install_update_handler.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 installupdate
     5  
     6  import (
     7  	moduleapi "github.com/verrazzano/verrazzano-modules/module-operator/apis/platform/v1alpha1"
     8  	modulestatus "github.com/verrazzano/verrazzano-modules/module-operator/controllers/module/status"
     9  	"github.com/verrazzano/verrazzano-modules/pkg/controller/result"
    10  	"github.com/verrazzano/verrazzano-modules/pkg/controller/spi/handlerspi"
    11  	vzerrors "github.com/verrazzano/verrazzano/pkg/controller/errors"
    12  	vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    13  	"github.com/verrazzano/verrazzano/platform-operator/constants"
    14  	"github.com/verrazzano/verrazzano/platform-operator/controllers/module/component-handler/common"
    15  )
    16  
    17  type ActionType string
    18  
    19  const (
    20  	InstallAction ActionType = constants.InstallOperation
    21  	UpdateAction  ActionType = constants.UpdateOperation
    22  )
    23  
    24  type ComponentHandler struct {
    25  	action ActionType
    26  }
    27  
    28  var (
    29  	_ handlerspi.StateMachineHandler = &ComponentHandler{}
    30  )
    31  
    32  func NewHandler(action ActionType) handlerspi.StateMachineHandler {
    33  	return &ComponentHandler{action: action}
    34  }
    35  
    36  // GetWorkName returns the work name
    37  func (h ComponentHandler) GetWorkName() string {
    38  	return string(h.action)
    39  }
    40  
    41  // IsWorkNeeded returns true if install/update is needed
    42  func (h ComponentHandler) IsWorkNeeded(ctx handlerspi.HandlerContext) (bool, result.Result) {
    43  	return true, result.NewResult()
    44  }
    45  
    46  // CheckDependencies checks if the dependencies are ready
    47  func (h ComponentHandler) CheckDependencies(ctx handlerspi.HandlerContext) result.Result {
    48  	return common.CheckDependencies(ctx, string(h.action), h.getStartedReason())
    49  }
    50  
    51  // PreWorkUpdateStatus does the pre-Work status update
    52  func (h ComponentHandler) PreWorkUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
    53  	module := ctx.CR.(*moduleapi.Module)
    54  
    55  	// Update the Verrazzano component status
    56  	nsn, err := common.GetVerrazzanoNSN(ctx)
    57  	if err != nil {
    58  		return result.NewResultShortRequeueDelayWithError(err)
    59  	}
    60  	sd := common.StatusData{
    61  		Vznsn:    *nsn,
    62  		CondType: vzapi.CondInstallStarted,
    63  		CompName: module.Spec.ModuleName,
    64  		Msg:      string(vzapi.CondInstallStarted),
    65  		Ready:    false,
    66  	}
    67  	res := common.UpdateVerrazzanoComponentStatus(ctx, sd)
    68  	if res.ShouldRequeue() {
    69  		return res
    70  	}
    71  
    72  	// Update the module status
    73  	return modulestatus.UpdateReadyConditionReconciling(ctx, module, h.getStartedReason())
    74  }
    75  
    76  // PreWork does the pre-work
    77  func (h ComponentHandler) PreWork(ctx handlerspi.HandlerContext) result.Result {
    78  	module := ctx.CR.(*moduleapi.Module)
    79  
    80  	compCtx, comp, err := common.GetComponentAndContext(ctx, string(h.action))
    81  	if err != nil {
    82  		return result.NewResultShortRequeueDelayWithError(err)
    83  	}
    84  
    85  	// Do the pre-install
    86  	if err := comp.PreInstall(compCtx); err != nil {
    87  		if !vzerrors.IsRetryableError(err) {
    88  			modulestatus.UpdateReadyConditionFailed(ctx, module, h.getStartedReason(), err.Error())
    89  		}
    90  		return result.NewResultShortRequeueDelayWithError(err)
    91  	}
    92  	modulestatus.UpdateReadyConditionReconciling(ctx, module, h.getStartedReason())
    93  	return result.NewResult()
    94  }
    95  
    96  // DoWorkUpdateStatus does th status update
    97  func (h ComponentHandler) DoWorkUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
    98  	return result.NewResult()
    99  }
   100  
   101  // DoWork installs the module using Helm
   102  func (h ComponentHandler) DoWork(ctx handlerspi.HandlerContext) result.Result {
   103  	module := ctx.CR.(*moduleapi.Module)
   104  
   105  	compCtx, comp, err := common.GetComponentAndContext(ctx, string(h.action))
   106  	if err != nil {
   107  		return result.NewResultShortRequeueDelayWithError(err)
   108  	}
   109  
   110  	if err := comp.Install(compCtx); err != nil {
   111  		if !vzerrors.IsRetryableError(err) {
   112  			modulestatus.UpdateReadyConditionFailed(ctx, module, h.getStartedReason(), err.Error())
   113  		}
   114  		return result.NewResultShortRequeueDelayWithError(err)
   115  	}
   116  	modulestatus.UpdateReadyConditionReconciling(ctx, module, h.getStartedReason())
   117  	return result.NewResult()
   118  }
   119  
   120  // IsWorkDone Indicates whether a module is installed and ready
   121  func (h ComponentHandler) IsWorkDone(ctx handlerspi.HandlerContext) (bool, result.Result) {
   122  	compCtx, comp, err := common.GetComponentAndContext(ctx, string(h.action))
   123  	if err != nil {
   124  		return false, result.NewResultShortRequeueDelayWithError(err)
   125  	}
   126  
   127  	ready := comp.IsReady(compCtx)
   128  	return ready, result.NewResult()
   129  }
   130  
   131  // PostWorkUpdateStatus does the post-work status update
   132  func (h ComponentHandler) PostWorkUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
   133  	return result.NewResult()
   134  }
   135  
   136  // PostWork does installation post-work
   137  func (h ComponentHandler) PostWork(ctx handlerspi.HandlerContext) result.Result {
   138  	module := ctx.CR.(*moduleapi.Module)
   139  
   140  	compCtx, comp, err := common.GetComponentAndContext(ctx, string(h.action))
   141  	if err != nil {
   142  		return result.NewResultShortRequeueDelayWithError(err)
   143  	}
   144  	if err := comp.PostInstall(compCtx); err != nil {
   145  		if !vzerrors.IsRetryableError(err) {
   146  			modulestatus.UpdateReadyConditionFailed(ctx, module, h.getStartedReason(), err.Error())
   147  		}
   148  		return result.NewResultShortRequeueDelayWithError(err)
   149  	}
   150  	modulestatus.UpdateReadyConditionReconciling(ctx, module, h.getStartedReason())
   151  	return result.NewResult()
   152  }
   153  
   154  // WorkCompletedUpdateStatus updates the status to completed
   155  func (h ComponentHandler) WorkCompletedUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
   156  	module := ctx.CR.(*moduleapi.Module)
   157  	var reason moduleapi.ModuleConditionReason
   158  	var cond vzapi.ConditionType
   159  
   160  	if h.action == InstallAction {
   161  		reason = moduleapi.ReadyReasonInstallSucceeded
   162  		cond = vzapi.CondInstallComplete
   163  	} else {
   164  		reason = moduleapi.ReadyReasonUpdateSucceeded
   165  		// Note, Verrazzano uses install condition for update
   166  		cond = vzapi.CondInstallComplete
   167  	}
   168  
   169  	// Update the Verrazzano component status
   170  	nsn, err := common.GetVerrazzanoNSN(ctx)
   171  	if err != nil {
   172  		return result.NewResultShortRequeueDelayWithError(err)
   173  	}
   174  	sd := common.StatusData{
   175  		Vznsn:       *nsn,
   176  		CondType:    cond,
   177  		CompName:    module.Spec.ModuleName,
   178  		CompVersion: module.Spec.Version,
   179  		Msg:         string(cond),
   180  		Ready:       true,
   181  	}
   182  	res := common.UpdateVerrazzanoComponentStatus(ctx, sd)
   183  	if res.ShouldRequeue() {
   184  		return res
   185  	}
   186  
   187  	// Update the module status
   188  	return modulestatus.UpdateReadyConditionSucceeded(ctx, module, reason)
   189  }
   190  
   191  func (h ComponentHandler) getStartedReason() moduleapi.ModuleConditionReason {
   192  	if h.action == InstallAction {
   193  		return moduleapi.ReadyReasonInstallStarted
   194  	}
   195  	return moduleapi.ReadyReasonUpdateStarted
   196  }