github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/process/update/initialisation_step.go (about) 1 package update 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/kyma-project/kyma-environment-broker/internal/storage/dberr" 8 9 "github.com/kyma-project/kyma-environment-broker/common/orchestration" 10 "github.com/kyma-project/kyma-environment-broker/internal" 11 kebError "github.com/kyma-project/kyma-environment-broker/internal/error" 12 "github.com/kyma-project/kyma-environment-broker/internal/process" 13 "github.com/kyma-project/kyma-environment-broker/internal/process/input" 14 "github.com/kyma-project/kyma-environment-broker/internal/storage" 15 "github.com/pivotal-cf/brokerapi/v8/domain" 16 "github.com/sirupsen/logrus" 17 ) 18 19 //go:generate mockery --name=RuntimeVersionConfiguratorForUpdating --output=automock --outpkg=automock --case=underscore 20 type RuntimeVersionConfiguratorForUpdating interface { 21 ForUpdating(op internal.Operation) (*internal.RuntimeVersionData, error) 22 } 23 24 type InitialisationStep struct { 25 operationManager *process.OperationManager 26 operationStorage storage.Operations 27 instanceStorage storage.Instances 28 runtimeVerConfigurator RuntimeVersionConfiguratorForUpdating 29 inputBuilder input.CreatorForPlan 30 } 31 32 func NewInitialisationStep(is storage.Instances, os storage.Operations, rvc RuntimeVersionConfiguratorForUpdating, b input.CreatorForPlan) *InitialisationStep { 33 return &InitialisationStep{ 34 operationManager: process.NewOperationManager(os), 35 operationStorage: os, 36 instanceStorage: is, 37 runtimeVerConfigurator: rvc, 38 inputBuilder: b, 39 } 40 } 41 42 func (s *InitialisationStep) Name() string { 43 return "Update_Kyma_Initialisation" 44 } 45 46 func (s *InitialisationStep) Run(operation internal.Operation, log logrus.FieldLogger) (internal.Operation, time.Duration, error) { 47 // Check concurrent deprovisioning (or suspension) operation (launched after target resolution) 48 // Terminate (preempt) upgrade immediately with succeeded 49 lastOp, err := s.operationStorage.GetLastOperation(operation.InstanceID) 50 if err != nil { 51 return operation, time.Minute, nil 52 } 53 54 if operation.State == orchestration.Pending { 55 if !lastOp.IsFinished() { 56 log.Infof("waiting for %s operation (%s) to be finished", lastOp.Type, lastOp.ID) 57 return operation, time.Minute, nil 58 } 59 60 // read the instance details (it could happen that created updating operation has outdated one) 61 instance, err := s.instanceStorage.GetByID(operation.InstanceID) 62 if err != nil { 63 if dberr.IsNotFound(err) { 64 log.Warnf("the instance already deprovisioned") 65 return s.operationManager.OperationFailed(operation, "the instance was already deprovisioned", err, log) 66 } 67 return operation, time.Second, nil 68 } 69 instance.Parameters.ErsContext = internal.InheritMissingERSContext(instance.Parameters.ErsContext, operation.ProvisioningParameters.ErsContext) 70 if _, err := s.instanceStorage.Update(*instance); err != nil { 71 log.Errorf("unable to update the instance, retrying") 72 return operation, time.Second, err 73 } 74 75 // suspension cleared runtimeID 76 if operation.RuntimeID == "" { 77 err = s.getRuntimeIdFromProvisioningOp(&operation) 78 if err != nil { 79 return s.operationManager.RetryOperation(operation, "error while getting runtime ID", err, 5*time.Second, 1*time.Minute, log) 80 } 81 } 82 log.Infof("Got runtime ID %s", operation.RuntimeID) 83 84 version, err := s.runtimeVerConfigurator.ForUpdating(operation) 85 if err != nil { 86 return s.operationManager.RetryOperation(operation, "error while getting runtime version", err, 5*time.Second, 1*time.Minute, log) 87 } 88 89 op, delay, _ := s.operationManager.UpdateOperation(operation, func(op *internal.Operation) { 90 op.State = domain.InProgress 91 op.InstanceDetails = instance.InstanceDetails 92 if op.ProvisioningParameters.ErsContext.SMOperatorCredentials == nil && lastOp.ProvisioningParameters.ErsContext.SMOperatorCredentials != nil { 93 op.ProvisioningParameters.ErsContext.SMOperatorCredentials = lastOp.ProvisioningParameters.ErsContext.SMOperatorCredentials 94 } 95 op.ProvisioningParameters.ErsContext = internal.InheritMissingERSContext(op.ProvisioningParameters.ErsContext, lastOp.ProvisioningParameters.ErsContext) 96 if version != nil { 97 op.RuntimeVersion = *version 98 } 99 }, log) 100 if delay != 0 { 101 log.Errorf("unable to update the operation (move to 'in progress'), retrying") 102 return operation, delay, nil 103 } 104 operation = op 105 } 106 107 if lastOp.Type == internal.OperationTypeDeprovision { 108 return s.operationManager.OperationSucceeded(operation, fmt.Sprintf("operation preempted by deprovisioning %s", lastOp.ID), log) 109 } 110 111 return s.initializeUpgradeShootRequest(operation, log) 112 } 113 114 func (s *InitialisationStep) getRuntimeIdFromProvisioningOp(operation *internal.Operation) error { 115 provOp, err := s.operationStorage.GetProvisioningOperationByInstanceID(operation.InstanceID) 116 if err != nil { 117 return fmt.Errorf("cannot get last provisioning operation for runtime id") 118 } 119 operation.RuntimeID = provOp.RuntimeID 120 return nil 121 } 122 123 func (s *InitialisationStep) initializeUpgradeShootRequest(operation internal.Operation, log logrus.FieldLogger) (internal.Operation, time.Duration, error) { 124 log.Infof("create provisioner input creator for plan ID %q", operation.ProvisioningParameters) 125 creator, err := s.inputBuilder.CreateUpgradeShootInput(operation.ProvisioningParameters, operation.RuntimeVersion) 126 switch { 127 case err == nil: 128 operation.InputCreator = creator 129 return operation, 0, nil // go to next step 130 case kebError.IsTemporaryError(err): 131 log.Errorf("cannot create upgrade shoot input creator at the moment for plan %s: %s", operation.ProvisioningParameters.PlanID, err) 132 return s.operationManager.RetryOperation(operation, "error while creating upgrade shoot input creator", err, 5*time.Second, 1*time.Minute, log) 133 default: 134 log.Errorf("cannot create input creator for plan %s: %s", operation.ProvisioningParameters.PlanID, err) 135 return s.operationManager.OperationFailed(operation, "cannot create provisioning input creator", err, log) 136 } 137 }