github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/process/provisioning/create_runtime_without_kyma_step.go (about) 1 package provisioning 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/kyma-project/control-plane/components/provisioner/pkg/gqlschema" 8 "github.com/kyma-project/kyma-environment-broker/internal" 9 kebError "github.com/kyma-project/kyma-environment-broker/internal/error" 10 "github.com/kyma-project/kyma-environment-broker/internal/process" 11 "github.com/kyma-project/kyma-environment-broker/internal/provisioner" 12 "github.com/kyma-project/kyma-environment-broker/internal/storage" 13 "github.com/kyma-project/kyma-environment-broker/internal/storage/dberr" 14 "github.com/sirupsen/logrus" 15 ) 16 17 const ( 18 // the time after which the operation is marked as expired 19 CreateRuntimeTimeout = 1 * time.Hour 20 21 brokerKeyPrefix = "broker_" 22 globalKeyPrefix = "global_" 23 ) 24 25 type CreateRuntimeWithoutKymaStep struct { 26 operationManager *process.OperationManager 27 instanceStorage storage.Instances 28 runtimeStateStorage storage.RuntimeStates 29 provisionerClient provisioner.Client 30 } 31 32 func NewCreateRuntimeWithoutKymaStep(os storage.Operations, runtimeStorage storage.RuntimeStates, is storage.Instances, cli provisioner.Client) *CreateRuntimeWithoutKymaStep { 33 return &CreateRuntimeWithoutKymaStep{ 34 operationManager: process.NewOperationManager(os), 35 instanceStorage: is, 36 provisionerClient: cli, 37 runtimeStateStorage: runtimeStorage, 38 } 39 } 40 41 func (s *CreateRuntimeWithoutKymaStep) Name() string { 42 return "Create_Runtime_Without_Kyma" 43 } 44 45 func (s *CreateRuntimeWithoutKymaStep) Run(operation internal.Operation, log logrus.FieldLogger) (internal.Operation, time.Duration, error) { 46 if operation.RuntimeID != "" { 47 log.Infof("RuntimeID already set %s, skipping", operation.RuntimeID) 48 return operation, 0, nil 49 } 50 if time.Since(operation.UpdatedAt) > CreateRuntimeTimeout { 51 log.Infof("operation has reached the time limit: updated operation time: %s", operation.UpdatedAt) 52 return s.operationManager.OperationFailed(operation, fmt.Sprintf("operation has reached the time limit: %s", CreateRuntimeTimeout), nil, log) 53 } 54 55 requestInput, err := s.createProvisionInput(operation) 56 if err != nil { 57 log.Errorf("Unable to create provisioning input: %s", err.Error()) 58 return s.operationManager.OperationFailed(operation, "invalid operation data - cannot create provisioning input", err, log) 59 } 60 61 log.Infof("call ProvisionRuntime: kubernetesVersion=%s, region=%s, provider=%s, name=%s, workers=%s, pods=%s, services=%s", 62 requestInput.ClusterConfig.GardenerConfig.KubernetesVersion, 63 requestInput.ClusterConfig.GardenerConfig.Region, 64 requestInput.ClusterConfig.GardenerConfig.Provider, 65 requestInput.ClusterConfig.GardenerConfig.Name, 66 requestInput.ClusterConfig.GardenerConfig.WorkerCidr, 67 valueOfString(requestInput.ClusterConfig.GardenerConfig.PodsCidr), 68 valueOfString(requestInput.ClusterConfig.GardenerConfig.ServicesCidr)) 69 70 provisionerResponse, err := s.provisionerClient.ProvisionRuntime(operation.ProvisioningParameters.ErsContext.GlobalAccountID, operation.ProvisioningParameters.ErsContext.SubAccountID, requestInput) 71 switch { 72 case kebError.IsTemporaryError(err): 73 log.Errorf("call to provisioner failed (temporary error): %s", err) 74 return operation, 5 * time.Second, nil 75 case err != nil: 76 log.Errorf("call to Provisioner failed: %s", err) 77 return s.operationManager.OperationFailed(operation, "call to the provisioner service failed", err, log) 78 } 79 log.Infof("Provisioning runtime in the Provisioner started, RuntimeID=%s, provisioner operation=%s", *provisionerResponse.RuntimeID, *provisionerResponse.ID) 80 81 repeat := time.Duration(0) 82 operation, repeat, _ = s.operationManager.UpdateOperation(operation, func(operation *internal.Operation) { 83 operation.ProvisionerOperationID = *provisionerResponse.ID 84 if provisionerResponse.RuntimeID != nil { 85 operation.RuntimeID = *provisionerResponse.RuntimeID 86 operation.Region = requestInput.ClusterConfig.GardenerConfig.Region 87 } 88 }, log) 89 if repeat != 0 { 90 log.Errorf("cannot save neither runtime ID nor region from provisioner") 91 return operation, 5 * time.Second, nil 92 } 93 94 rs := internal.NewRuntimeState(*provisionerResponse.RuntimeID, operation.ID, requestInput.KymaConfig, requestInput.ClusterConfig.GardenerConfig) 95 rs.KymaVersion = operation.RuntimeVersion.Version 96 err = s.runtimeStateStorage.Insert(rs) 97 98 if err != nil { 99 log.Errorf("cannot insert runtimeState: %s", err) 100 return operation, 10 * time.Second, nil 101 } 102 103 err = s.updateInstance(operation.InstanceID, 104 *provisionerResponse.RuntimeID, 105 requestInput.ClusterConfig.GardenerConfig.Region) 106 107 switch { 108 case err == nil: 109 case dberr.IsConflict(err): 110 err := s.updateInstance(operation.InstanceID, *provisionerResponse.RuntimeID, requestInput.ClusterConfig.GardenerConfig.Region) 111 if err != nil { 112 log.Errorf("cannot update instance: %s", err) 113 return operation, 1 * time.Minute, nil 114 } 115 } 116 117 log.Info("runtime creation process initiated successfully") 118 return operation, 0, nil 119 } 120 121 func valueOfString(val *string) string { 122 if val == nil { 123 return "<nil>" 124 } 125 return *val 126 } 127 128 func (s *CreateRuntimeWithoutKymaStep) updateInstance(id, runtimeID, region string) error { 129 instance, err := s.instanceStorage.GetByID(id) 130 if err != nil { 131 return fmt.Errorf("while getting instance: %w", err) 132 } 133 instance.RuntimeID = runtimeID 134 instance.ProviderRegion = region 135 _, err = s.instanceStorage.Update(*instance) 136 if err != nil { 137 return fmt.Errorf("while updating instance: %w", err) 138 } 139 140 return nil 141 } 142 143 func (s *CreateRuntimeWithoutKymaStep) createProvisionInput(operation internal.Operation) (gqlschema.ProvisionRuntimeInput, error) { 144 operation.InputCreator.SetProvisioningParameters(operation.ProvisioningParameters) 145 operation.InputCreator.SetShootName(operation.ShootName) 146 operation.InputCreator.SetShootDomain(operation.ShootDomain) 147 operation.InputCreator.SetShootDNSProviders(operation.ShootDNSProviders) 148 operation.InputCreator.SetLabel(brokerKeyPrefix+"instance_id", operation.InstanceID) 149 operation.InputCreator.SetLabel(globalKeyPrefix+"subaccount_id", operation.ProvisioningParameters.ErsContext.SubAccountID) 150 operation.InputCreator.SetLabel(grafanaURLLabel, fmt.Sprintf("https://grafana.%s", operation.ShootDomain)) 151 request, err := operation.InputCreator.CreateProvisionClusterInput() 152 if err != nil { 153 return request, fmt.Errorf("while building input for provisioner: %w", err) 154 } 155 request.ClusterConfig.GardenerConfig.ShootNetworkingFilterDisabled = operation.ProvisioningParameters.ErsContext.DisableEnterprisePolicyFilter() 156 request.ClusterConfig.GardenerConfig.EuAccess = &operation.InstanceDetails.EuAccess 157 158 return request, nil 159 }