github.com/verrazzano/verrazzano@v1.7.0/platform-operator/controllers/module/component-handler/delete/delete_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 delete
     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  	"k8s.io/apimachinery/pkg/api/meta"
    16  )
    17  
    18  type ComponentHandler struct{}
    19  
    20  var (
    21  	_ handlerspi.StateMachineHandler = &ComponentHandler{}
    22  )
    23  
    24  func NewHandler() handlerspi.StateMachineHandler {
    25  	return &ComponentHandler{}
    26  }
    27  
    28  // GetWorkName returns the work name
    29  func (h ComponentHandler) GetWorkName() string {
    30  	return "uninstall"
    31  }
    32  
    33  // IsWorkNeeded returns true if uninstall is needed
    34  func (h ComponentHandler) IsWorkNeeded(ctx handlerspi.HandlerContext) (bool, result.Result) {
    35  	// Always return true so that the post-uninstall can run in the case that the VPO
    36  	// was restarted
    37  	return true, result.NewResult()
    38  }
    39  
    40  // CheckDependencies checks if the dependencies are ready
    41  func (h ComponentHandler) CheckDependencies(ctx handlerspi.HandlerContext) result.Result {
    42  	return result.NewResult()
    43  }
    44  
    45  // PreWorkUpdateStatus does the lifecycle pre-Work status update
    46  func (h ComponentHandler) PreWorkUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
    47  	module := ctx.CR.(*moduleapi.Module)
    48  
    49  	// Update the Verrazzano component status
    50  	nsn, err := common.GetVerrazzanoNSN(ctx)
    51  	if err != nil {
    52  		return result.NewResultShortRequeueDelayWithError(err)
    53  	}
    54  	sd := common.StatusData{
    55  		Vznsn:    *nsn,
    56  		CondType: vzapi.CondUninstallStarted,
    57  		CompName: module.Spec.ModuleName,
    58  		Msg:      string(vzapi.CondUninstallStarted),
    59  		Ready:    false,
    60  	}
    61  	res := common.UpdateVerrazzanoComponentStatus(ctx, sd)
    62  	if res.ShouldRequeue() {
    63  		return res
    64  	}
    65  
    66  	// Update the module status
    67  	return modulestatus.UpdateReadyConditionReconciling(ctx, module, moduleapi.ReadyReasonUninstallStarted)
    68  }
    69  
    70  // PreWork does the pre-work
    71  func (h ComponentHandler) PreWork(ctx handlerspi.HandlerContext) result.Result {
    72  	module := ctx.CR.(*moduleapi.Module)
    73  
    74  	compCtx, comp, err := common.GetComponentAndContext(ctx, constants.UninstallOperation)
    75  	if err != nil {
    76  		return result.NewResultShortRequeueDelayWithError(err)
    77  	}
    78  
    79  	// Do the pre-delete
    80  	err = ignoreMissingCRD(comp.PreUninstall(compCtx))
    81  
    82  	if err != nil {
    83  		if !vzerrors.IsRetryableError(err) {
    84  			modulestatus.UpdateReadyConditionFailed(ctx, module, moduleapi.ReadyReasonUninstallStarted, err.Error())
    85  		}
    86  		return result.NewResultShortRequeueDelayWithError(err)
    87  	}
    88  	return result.NewResult()
    89  }
    90  
    91  // DoWorkUpdateStatus does the work status update
    92  func (h ComponentHandler) DoWorkUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
    93  	return result.NewResult()
    94  }
    95  
    96  // DoWork uninstalls the module using Helm
    97  func (h ComponentHandler) DoWork(ctx handlerspi.HandlerContext) result.Result {
    98  	module := ctx.CR.(*moduleapi.Module)
    99  
   100  	compCtx, comp, err := common.GetComponentAndContext(ctx, constants.UninstallOperation)
   101  	if err != nil {
   102  		return result.NewResultShortRequeueDelayWithError(err)
   103  	}
   104  
   105  	err = ignoreMissingCRD(comp.Uninstall(compCtx))
   106  	if err != nil {
   107  		if !vzerrors.IsRetryableError(err) {
   108  			modulestatus.UpdateReadyConditionFailed(ctx, module, moduleapi.ReadyReasonUninstallStarted, err.Error())
   109  		}
   110  		return result.NewResultShortRequeueDelayWithError(err)
   111  	}
   112  	return result.NewResult()
   113  }
   114  
   115  // IsWorkDone Indicates whether a module is uninstalled
   116  func (h ComponentHandler) IsWorkDone(ctx handlerspi.HandlerContext) (bool, result.Result) {
   117  	compCtx, comp, err := common.GetComponentAndContext(ctx, constants.UninstallOperation)
   118  	if err != nil {
   119  		return false, result.NewResultShortRequeueDelayWithError(err)
   120  	}
   121  
   122  	exists, err := comp.Exists(compCtx)
   123  	if err != nil {
   124  		ctx.Log.ErrorfThrottled("Error checking if Helm release exists for %s/%s", ctx.HelmRelease.Namespace, ctx.HelmRelease.Name)
   125  		return false, result.NewResultShortRequeueDelayWithError(err)
   126  	}
   127  	return !exists, result.NewResult()
   128  }
   129  
   130  // PostWorkUpdateStatus does the post-work status update
   131  func (h ComponentHandler) PostWorkUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
   132  	return result.NewResult()
   133  }
   134  
   135  // PostWork does installation pre-work
   136  func (h ComponentHandler) PostWork(ctx handlerspi.HandlerContext) result.Result {
   137  	module := ctx.CR.(*moduleapi.Module)
   138  
   139  	compCtx, comp, err := common.GetComponentAndContext(ctx, constants.UninstallOperation)
   140  	if err != nil {
   141  		return result.NewResultShortRequeueDelayWithError(err)
   142  	}
   143  
   144  	err = ignoreMissingCRD(comp.PostUninstall(compCtx))
   145  	if err != nil {
   146  		if !vzerrors.IsRetryableError(err) {
   147  			modulestatus.UpdateReadyConditionFailed(ctx, module, moduleapi.ReadyReasonUninstallStarted, err.Error())
   148  		}
   149  		return result.NewResultShortRequeueDelayWithError(err)
   150  	}
   151  	return result.NewResult()
   152  }
   153  
   154  // WorkCompletedUpdateStatus does the lifecycle completed Work status update
   155  func (h ComponentHandler) WorkCompletedUpdateStatus(ctx handlerspi.HandlerContext) result.Result {
   156  	module := ctx.CR.(*moduleapi.Module)
   157  
   158  	// Update the Verrazzano component status to disabled
   159  	vzNSN, err := common.GetVerrazzanoNSN(ctx)
   160  	if err != nil {
   161  		return result.NewResultShortRequeueDelayWithError(err)
   162  	}
   163  
   164  	res := common.UpdateVerrazzanoComponentStatusToDisabled(ctx, *vzNSN, module.Spec.ModuleName)
   165  	if res.ShouldRequeue() {
   166  		return res
   167  	}
   168  
   169  	// Update the module status
   170  	return modulestatus.UpdateReadyConditionSucceeded(ctx, module, moduleapi.ReadyReasonUninstallSucceeded)
   171  }
   172  
   173  func ignoreMissingCRD(err error) error {
   174  	if err == nil {
   175  		return nil
   176  	}
   177  	// Ignore if CRD doesn't exist
   178  	if _, ok := err.(*meta.NoKindMatchError); ok {
   179  		return nil
   180  	}
   181  	return err
   182  }