github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/model.go (about) 1 package internal 2 3 import ( 4 "database/sql" 5 "fmt" 6 "strconv" 7 "strings" 8 "time" 9 10 "github.com/kyma-project/kyma-environment-broker/internal/euaccess" 11 12 "sigs.k8s.io/controller-runtime/pkg/client" 13 14 "github.com/google/uuid" 15 reconcilerApi "github.com/kyma-incubator/reconciler/pkg/keb" 16 "github.com/kyma-project/control-plane/components/provisioner/pkg/gqlschema" 17 "github.com/kyma-project/kyma-environment-broker/common/gardener" 18 "github.com/kyma-project/kyma-environment-broker/common/orchestration" 19 kebError "github.com/kyma-project/kyma-environment-broker/internal/error" 20 "github.com/kyma-project/kyma-environment-broker/internal/events" 21 "github.com/kyma-project/kyma-environment-broker/internal/ptr" 22 "github.com/pivotal-cf/brokerapi/v8/domain" 23 log "github.com/sirupsen/logrus" 24 ) 25 26 type ProvisionerInputCreator interface { 27 SetProvisioningParameters(params ProvisioningParameters) ProvisionerInputCreator 28 SetShootName(string) ProvisionerInputCreator 29 SetLabel(key, value string) ProvisionerInputCreator 30 // Deprecated, use: AppendOverrides 31 SetOverrides(component string, overrides []*gqlschema.ConfigEntryInput) ProvisionerInputCreator 32 AppendOverrides(component string, overrides []*gqlschema.ConfigEntryInput) ProvisionerInputCreator 33 AppendGlobalOverrides(overrides []*gqlschema.ConfigEntryInput) ProvisionerInputCreator 34 CreateProvisionRuntimeInput() (gqlschema.ProvisionRuntimeInput, error) 35 CreateUpgradeRuntimeInput() (gqlschema.UpgradeRuntimeInput, error) 36 CreateUpgradeShootInput() (gqlschema.UpgradeShootInput, error) 37 EnableOptionalComponent(componentName string) ProvisionerInputCreator 38 DisableOptionalComponent(componentName string) ProvisionerInputCreator 39 Provider() CloudProvider 40 Configuration() *ConfigForPlan 41 42 CreateClusterConfiguration() (reconcilerApi.Cluster, error) 43 CreateProvisionClusterInput() (gqlschema.ProvisionRuntimeInput, error) 44 SetKubeconfig(kcfg string) ProvisionerInputCreator 45 SetRuntimeID(runtimeID string) ProvisionerInputCreator 46 SetInstanceID(instanceID string) ProvisionerInputCreator 47 SetShootDomain(shootDomain string) ProvisionerInputCreator 48 SetShootDNSProviders(dnsProviders gardener.DNSProvidersData) ProvisionerInputCreator 49 SetClusterName(name string) ProvisionerInputCreator 50 SetOIDCLastValues(oidcConfig gqlschema.OIDCConfigInput) ProvisionerInputCreator 51 } 52 53 // GitKymaProject and GitKymaRepo define public Kyma GitHub parameters used for 54 // external evaluation. 55 const ( 56 GitKymaProject = "kyma-project" 57 GitKymaRepo = "kyma" 58 ) 59 60 type AvsEvaluationStatus struct { 61 Current string `json:"current_value"` 62 Original string `json:"original_value"` 63 } 64 65 type AvsLifecycleData struct { 66 AvsEvaluationInternalId int64 `json:"avs_evaluation_internal_id"` 67 AVSEvaluationExternalId int64 `json:"avs_evaluation_external_id"` 68 69 AvsInternalEvaluationStatus AvsEvaluationStatus `json:"avs_internal_evaluation_status"` 70 AvsExternalEvaluationStatus AvsEvaluationStatus `json:"avs_external_evaluation_status"` 71 72 AVSInternalEvaluationDeleted bool `json:"avs_internal_evaluation_deleted"` 73 AVSExternalEvaluationDeleted bool `json:"avs_external_evaluation_deleted"` 74 } 75 76 // RuntimeVersionOrigin defines the possible sources of the Kyma Version parameter 77 type RuntimeVersionOrigin string 78 79 const ( 80 Parameters RuntimeVersionOrigin = "parameters" 81 Defaults RuntimeVersionOrigin = "defaults" 82 AccountMapping RuntimeVersionOrigin = "account-mapping" 83 ) 84 85 // RuntimeVersionData describes the Kyma Version used for the cluster 86 // provisioning or upgrade 87 type RuntimeVersionData struct { 88 Version string `json:"version"` 89 Origin RuntimeVersionOrigin `json:"origin"` 90 MajorVersion int `json:"major_version"` 91 } 92 93 func (rv RuntimeVersionData) IsEmpty() bool { 94 return rv.Version == "" 95 } 96 97 func NewEmptyRuntimeVersion() *RuntimeVersionData { 98 return &RuntimeVersionData{Version: "not-defined", Origin: Defaults, MajorVersion: 2} 99 } 100 101 func NewRuntimeVersionFromParameters(version string, majorVersion int) *RuntimeVersionData { 102 return &RuntimeVersionData{Version: version, Origin: Parameters, MajorVersion: majorVersion} 103 } 104 105 func NewRuntimeVersionFromDefaults(version string) *RuntimeVersionData { 106 defaultMajorVerNum := DetermineMajorVersion(version) 107 return &RuntimeVersionData{Version: version, Origin: Defaults, MajorVersion: defaultMajorVerNum} 108 } 109 110 func DetermineMajorVersion(version string) int { 111 splitVer := strings.Split(version, ".") 112 majorVerNum, _ := strconv.Atoi(splitVer[0]) 113 return majorVerNum 114 } 115 116 func NewRuntimeVersionFromAccountMapping(version string, majorVersion int) *RuntimeVersionData { 117 return &RuntimeVersionData{Version: version, Origin: AccountMapping, MajorVersion: majorVersion} 118 } 119 120 type EventHub struct { 121 Deleted bool `json:"event_hub_deleted"` 122 } 123 124 type Instance struct { 125 InstanceID string 126 RuntimeID string 127 GlobalAccountID string 128 SubscriptionGlobalAccountID string 129 SubAccountID string 130 ServiceID string 131 ServiceName string 132 ServicePlanID string 133 ServicePlanName string 134 135 DashboardURL string 136 Parameters ProvisioningParameters 137 ProviderRegion string 138 139 InstanceDetails InstanceDetails 140 141 CreatedAt time.Time 142 UpdatedAt time.Time 143 DeletedAt time.Time 144 ExpiredAt *time.Time 145 146 Version int 147 Provider CloudProvider 148 Reconcilable bool 149 } 150 151 func (i *Instance) IsExpired() bool { 152 return i.ExpiredAt != nil 153 } 154 155 func (i *Instance) GetSubscriptionGlobalAccoundID() string { 156 if i.SubscriptionGlobalAccountID != "" { 157 return i.SubscriptionGlobalAccountID 158 } else { 159 return i.GlobalAccountID 160 } 161 } 162 163 func (i *Instance) GetInstanceDetails() (InstanceDetails, error) { 164 result := i.InstanceDetails 165 //overwrite RuntimeID in InstanceDetails with Instance.RuntimeID 166 //needed for runtimes suspended without clearing RuntimeID in deprovisioning operation 167 result.RuntimeID = i.RuntimeID 168 return result, nil 169 } 170 171 // OperationType defines the possible types of an asynchronous operation to a broker. 172 type OperationType string 173 174 const ( 175 // OperationTypeProvision means provisioning OperationType 176 OperationTypeProvision OperationType = "provision" 177 // OperationTypeDeprovision means deprovision OperationType 178 OperationTypeDeprovision OperationType = "deprovision" 179 // OperationTypeUndefined means undefined OperationType 180 OperationTypeUndefined OperationType = "" 181 // OperationTypeUpgradeKyma means upgrade Kyma OperationType 182 OperationTypeUpgradeKyma OperationType = "upgradeKyma" 183 // OperationTypeUpdate means update 184 OperationTypeUpdate OperationType = "update" 185 // OperationTypeUpgradeCluster means upgrade cluster (shoot) OperationType 186 OperationTypeUpgradeCluster OperationType = "upgradeCluster" 187 ) 188 189 type Operation struct { 190 // following fields are serialized to JSON and stored in the storage 191 InstanceDetails 192 193 ID string `json:"-"` 194 Version int `json:"-"` 195 CreatedAt time.Time `json:"-"` 196 UpdatedAt time.Time `json:"-"` 197 Type OperationType `json:"-"` 198 199 InstanceID string `json:"-"` 200 ProvisionerOperationID string `json:"-"` 201 State domain.LastOperationState `json:"-"` 202 Description string `json:"-"` 203 ProvisioningParameters ProvisioningParameters `json:"-"` 204 205 InputCreator ProvisionerInputCreator `json:"-"` 206 207 // OrchestrationID specifies the origin orchestration which triggers the operation, empty for OSB operations (provisioning/deprovisioning) 208 OrchestrationID string `json:"-"` 209 FinishedStages []string `json:"-"` 210 LastError kebError.LastError `json:"-"` 211 212 // PROVISIONING 213 RuntimeVersion RuntimeVersionData `json:"runtime_version"` 214 DashboardURL string `json:"dashboardURL"` 215 216 // DEPROVISIONING 217 // Temporary indicates that this deprovisioning operation must not remove the instance 218 Temporary bool `json:"temporary"` 219 ClusterConfigurationDeleted bool `json:"clusterConfigurationDeleted"` 220 Retries int `json:"-"` 221 ReconcilerDeregistrationAt time.Time `json:"reconcilerDeregistrationAt"` 222 ExcutedButNotCompleted []string `json:"excutedButNotCompleted"` 223 UserAgent string `json:"userAgent,omitempty"` 224 225 // UPDATING 226 UpdatingParameters UpdatingParametersDTO `json:"updating_parameters"` 227 CheckReconcilerStatus bool `json:"check_reconciler_status"` 228 K8sClient client.Client `json:"-"` 229 230 // following fields are not stored in the storage 231 232 // Last runtime state payload 233 LastRuntimeState RuntimeState `json:"-"` 234 235 // Flag used by the steps regarding BTP-Operator credentials update 236 // denotes whether the payload to reconciler differs from last runtime state 237 RequiresReconcilerUpdate bool `json:"-"` 238 239 // UPGRADE KYMA 240 orchestration.RuntimeOperation `json:"runtime_operation"` 241 ClusterConfigurationApplied bool `json:"cluster_configuration_applied"` 242 243 // KymaTemplate is read from the configuration then used in the apply_kyma step 244 KymaTemplate string `json:"KymaTemplate"` 245 } 246 247 func (o *Operation) IsFinished() bool { 248 return o.State != orchestration.InProgress && o.State != orchestration.Pending && o.State != orchestration.Canceling && o.State != orchestration.Retrying 249 } 250 251 func (o *Operation) EventInfof(fmt string, args ...any) { 252 events.Infof(o.InstanceID, o.ID, fmt, args...) 253 } 254 255 func (o *Operation) EventErrorf(err error, fmt string, args ...any) { 256 events.Errorf(o.InstanceID, o.ID, err, fmt, args...) 257 } 258 259 // Orchestration holds all information about an orchestration. 260 // Orchestration performs operations of a specific type (UpgradeKymaOperation, UpgradeClusterOperation) 261 // on specific targets of SKRs. 262 type Orchestration struct { 263 OrchestrationID string 264 Type orchestration.Type 265 State string 266 Description string 267 CreatedAt time.Time 268 UpdatedAt time.Time 269 Parameters orchestration.Parameters 270 } 271 272 func (o *Orchestration) IsFinished() bool { 273 return o.State == orchestration.Succeeded || o.State == orchestration.Failed || o.State == orchestration.Canceled 274 } 275 276 // IsCanceled returns true if orchestration's cancellation endpoint was ever triggered 277 func (o *Orchestration) IsCanceled() bool { 278 return o.State == orchestration.Canceling || o.State == orchestration.Canceled 279 } 280 281 type InstanceWithOperation struct { 282 Instance 283 284 Type sql.NullString 285 State sql.NullString 286 Description sql.NullString 287 OpCreatedAt time.Time 288 IsSuspensionOp bool 289 } 290 291 type InstanceDetails struct { 292 Avs AvsLifecycleData `json:"avs"` 293 EventHub EventHub `json:"eh"` 294 295 SubAccountID string `json:"sub_account_id"` 296 RuntimeID string `json:"runtime_id"` 297 ShootName string `json:"shoot_name"` 298 ShootDomain string `json:"shoot_domain"` 299 ClusterName string `json:"clusterName"` 300 ShootDNSProviders gardener.DNSProvidersData `json:"shoot_dns_providers"` 301 Monitoring MonitoringData `json:"monitoring"` 302 EDPCreated bool `json:"edp_created"` 303 304 ClusterConfigurationVersion int64 `json:"cluster_configuration_version"` 305 Kubeconfig string `json:"-"` 306 307 ServiceManagerClusterID string `json:"sm_cluster_id"` 308 309 KymaResourceNamespace string `json:"kyma_resource_namespace"` 310 KymaResourceName string `json:"kyma_resource_name"` 311 312 EuAccess bool `json:"eu_access"` 313 314 // CompassRuntimeId - a runtime ID created by the Compass. Existing instances has a nil value (because the field was not existing) - it means the compass runtime Id is equal to runtime ID. 315 // If the value is an empty string - it means the runtime was not registered by Provisioner in the Compass. 316 // Should be removed after the migration of compass registration is completed 317 CompassRuntimeId *string 318 } 319 320 // IsRegisteredInCompassByProvisioner returns true, if the runtime was registered in Compass by Provisioner 321 func (i *InstanceDetails) IsRegisteredInCompassByProvisioner() bool { 322 return i.CompassRuntimeId == nil || *i.CompassRuntimeId != "" 323 } 324 325 func (i *InstanceDetails) SetCompassRuntimeIdNotRegisteredByProvisioner() { 326 i.CompassRuntimeId = ptr.String("") 327 } 328 329 // GetCompassRuntimeId provides a compass runtime Id registered by Provisioner or empty string if it was not provisioned by Provisioner. 330 func (i *InstanceDetails) GetCompassRuntimeId() string { 331 // for backward compatibility, if CompassRuntimeID field was not set, use RuntimeId 332 if i.CompassRuntimeId == nil { 333 return i.RuntimeID 334 } 335 return *i.CompassRuntimeId 336 } 337 338 // ProvisioningOperation holds all information about provisioning operation 339 type ProvisioningOperation struct { 340 Operation 341 } 342 343 type MonitoringData struct { 344 Username string `json:"username"` 345 Password string `json:"password"` 346 } 347 348 // DeprovisioningOperation holds all information about de-provisioning operation 349 type DeprovisioningOperation struct { 350 Operation 351 } 352 353 func (op *Operation) TimeSinceReconcilerDeregistrationTriggered() time.Duration { 354 if op.ReconcilerDeregistrationAt.IsZero() { 355 return 0 356 } 357 return time.Since(op.ReconcilerDeregistrationAt) 358 } 359 360 type UpdatingOperation struct { 361 Operation 362 } 363 364 // UpgradeKymaOperation holds all information about upgrade Kyma operation 365 type UpgradeKymaOperation struct { 366 Operation 367 } 368 369 // UpgradeClusterOperation holds all information about upgrade cluster (shoot) operation 370 type UpgradeClusterOperation struct { 371 Operation 372 } 373 374 func NewRuntimeState(runtimeID, operationID string, kymaConfig *gqlschema.KymaConfigInput, clusterConfig *gqlschema.GardenerConfigInput) RuntimeState { 375 var ( 376 kymaConfigInput gqlschema.KymaConfigInput 377 clusterConfigInput gqlschema.GardenerConfigInput 378 ) 379 if kymaConfig != nil { 380 kymaConfigInput = *kymaConfig 381 } 382 if clusterConfig != nil { 383 clusterConfigInput = *clusterConfig 384 } 385 386 return RuntimeState{ 387 ID: uuid.New().String(), 388 CreatedAt: time.Now(), 389 RuntimeID: runtimeID, 390 OperationID: operationID, 391 KymaConfig: kymaConfigInput, 392 ClusterConfig: clusterConfigInput, 393 } 394 } 395 396 func NewRuntimeStateWithReconcilerInput(runtimeID, operationID string, reconcilerInput *reconcilerApi.Cluster) RuntimeState { 397 return RuntimeState{ 398 ID: uuid.New().String(), 399 CreatedAt: time.Now(), 400 RuntimeID: runtimeID, 401 OperationID: operationID, 402 ClusterSetup: reconcilerInput, 403 } 404 } 405 406 type RuntimeState struct { 407 ID string `json:"id"` 408 409 CreatedAt time.Time `json:"created_at"` 410 411 RuntimeID string `json:"runtimeId"` 412 OperationID string `json:"operationId"` 413 414 KymaConfig gqlschema.KymaConfigInput `json:"kymaConfig"` 415 ClusterConfig gqlschema.GardenerConfigInput `json:"clusterConfig"` 416 ClusterSetup *reconcilerApi.Cluster `json:"clusterSetup,omitempty"` 417 418 KymaVersion string `json:"kyma_version"` 419 } 420 421 func (r *RuntimeState) GetKymaConfig() gqlschema.KymaConfigInput { 422 if r.ClusterSetup != nil { 423 return r.buildKymaConfigFromClusterSetup() 424 } 425 return r.KymaConfig 426 } 427 428 func (r *RuntimeState) GetKymaVersion() string { 429 if r.KymaVersion != "" { 430 return r.KymaVersion 431 } 432 if r.ClusterSetup != nil { 433 return r.ClusterSetup.KymaConfig.Version 434 } 435 return r.KymaConfig.Version 436 } 437 438 func (r *RuntimeState) buildKymaConfigFromClusterSetup() gqlschema.KymaConfigInput { 439 var components []*gqlschema.ComponentConfigurationInput 440 for _, cmp := range r.ClusterSetup.KymaConfig.Components { 441 var config []*gqlschema.ConfigEntryInput 442 for _, cfg := range cmp.Configuration { 443 configEntryInput := &gqlschema.ConfigEntryInput{ 444 Key: cfg.Key, 445 Value: fmt.Sprint(cfg.Value), 446 Secret: ptr.Bool(cfg.Secret), 447 } 448 config = append(config, configEntryInput) 449 } 450 451 componentConfigurationInput := &gqlschema.ComponentConfigurationInput{ 452 Component: cmp.Component, 453 Namespace: cmp.Namespace, 454 SourceURL: &cmp.URL, 455 Configuration: config, 456 } 457 components = append(components, componentConfigurationInput) 458 } 459 460 profile := gqlschema.KymaProfile(r.ClusterSetup.KymaConfig.Profile) 461 kymaConfig := gqlschema.KymaConfigInput{ 462 Version: r.ClusterSetup.KymaConfig.Version, 463 Profile: &profile, 464 Components: components, 465 } 466 467 return kymaConfig 468 } 469 470 // OperationStats provide number of operations per type and state 471 type OperationStats struct { 472 Provisioning map[domain.LastOperationState]int 473 Deprovisioning map[domain.LastOperationState]int 474 } 475 476 // InstanceStats provide number of instances per Global Account ID 477 type InstanceStats struct { 478 TotalNumberOfInstances int 479 PerGlobalAccountID map[string]int 480 } 481 482 // ERSContextStats provides aggregated information regarding ERSContext 483 type ERSContextStats struct { 484 LicenseType map[string]int 485 } 486 487 // NewProvisioningOperation creates a fresh (just starting) instance of the ProvisioningOperation 488 func NewProvisioningOperation(instanceID string, parameters ProvisioningParameters) (ProvisioningOperation, error) { 489 return NewProvisioningOperationWithID(uuid.New().String(), instanceID, parameters) 490 } 491 492 // NewProvisioningOperationWithID creates a fresh (just starting) instance of the ProvisioningOperation with provided ID 493 func NewProvisioningOperationWithID(operationID, instanceID string, parameters ProvisioningParameters) (ProvisioningOperation, error) { 494 return ProvisioningOperation{ 495 Operation: Operation{ 496 ID: operationID, 497 Version: 0, 498 Description: "Operation created", 499 InstanceID: instanceID, 500 State: domain.InProgress, 501 CreatedAt: time.Now(), 502 UpdatedAt: time.Now(), 503 Type: OperationTypeProvision, 504 ProvisioningParameters: parameters, 505 RuntimeOperation: orchestration.RuntimeOperation{ 506 Runtime: orchestration.Runtime{ 507 GlobalAccountID: parameters.ErsContext.GlobalAccountID, 508 }, 509 }, 510 InstanceDetails: InstanceDetails{ 511 SubAccountID: parameters.ErsContext.SubAccountID, 512 Kubeconfig: parameters.Parameters.Kubeconfig, 513 EuAccess: euaccess.IsEURestrictedAccess(parameters.PlatformRegion), 514 }, 515 FinishedStages: make([]string, 0), 516 LastError: kebError.LastError{}, 517 }, 518 }, nil 519 } 520 521 // NewDeprovisioningOperationWithID creates a fresh (just starting) instance of the DeprovisioningOperation with provided ID 522 func NewDeprovisioningOperationWithID(operationID string, instance *Instance) (DeprovisioningOperation, error) { 523 details, err := instance.GetInstanceDetails() 524 if err != nil { 525 return DeprovisioningOperation{}, err 526 } 527 return DeprovisioningOperation{ 528 Operation: Operation{ 529 RuntimeOperation: orchestration.RuntimeOperation{ 530 Runtime: orchestration.Runtime{GlobalAccountID: instance.GlobalAccountID, RuntimeID: instance.RuntimeID, Region: instance.ProviderRegion}, 531 }, 532 ID: operationID, 533 Version: 0, 534 Description: "Operation created", 535 InstanceID: instance.InstanceID, 536 State: orchestration.Pending, 537 CreatedAt: time.Now(), 538 UpdatedAt: time.Now(), 539 Type: OperationTypeDeprovision, 540 InstanceDetails: details, 541 FinishedStages: make([]string, 0), 542 ProvisioningParameters: instance.Parameters, 543 }, 544 }, nil 545 } 546 547 func NewUpdateOperation(operationID string, instance *Instance, updatingParams UpdatingParametersDTO) Operation { 548 549 op := Operation{ 550 ID: operationID, 551 Version: 0, 552 Description: "Operation created", 553 InstanceID: instance.InstanceID, 554 State: orchestration.Pending, 555 CreatedAt: time.Now(), 556 UpdatedAt: time.Now(), 557 Type: OperationTypeUpdate, 558 InstanceDetails: instance.InstanceDetails, 559 FinishedStages: make([]string, 0), 560 ProvisioningParameters: instance.Parameters, 561 UpdatingParameters: updatingParams, 562 RuntimeOperation: orchestration.RuntimeOperation{ 563 Runtime: orchestration.Runtime{ 564 Region: instance.ProviderRegion}, 565 }, 566 } 567 if updatingParams.OIDC != nil { 568 op.ProvisioningParameters.Parameters.OIDC = updatingParams.OIDC 569 } 570 571 if len(updatingParams.RuntimeAdministrators) != 0 { 572 op.ProvisioningParameters.Parameters.RuntimeAdministrators = updatingParams.RuntimeAdministrators 573 } 574 575 updatingParams.UpdateAutoScaler(&op.ProvisioningParameters.Parameters) 576 if updatingParams.MachineType != nil && *updatingParams.MachineType != "" { 577 op.ProvisioningParameters.Parameters.MachineType = updatingParams.MachineType 578 } 579 580 return op 581 } 582 583 // NewSuspensionOperationWithID creates a fresh (just starting) instance of the DeprovisioningOperation which does not remove the instance. 584 func NewSuspensionOperationWithID(operationID string, instance *Instance) DeprovisioningOperation { 585 return DeprovisioningOperation{ 586 Operation: Operation{ 587 ID: operationID, 588 Version: 0, 589 Description: "Operation created", 590 InstanceID: instance.InstanceID, 591 State: orchestration.Pending, 592 CreatedAt: time.Now(), 593 UpdatedAt: time.Now(), 594 Type: OperationTypeDeprovision, 595 InstanceDetails: instance.InstanceDetails, 596 ProvisioningParameters: instance.Parameters, 597 FinishedStages: make([]string, 0), 598 Temporary: true, 599 RuntimeOperation: orchestration.RuntimeOperation{ 600 Runtime: orchestration.Runtime{ 601 Region: instance.ProviderRegion}, 602 }, 603 }, 604 } 605 } 606 607 func (o *Operation) FinishStage(stageName string) { 608 if stageName == "" { 609 log.Warnf("Attempt to add empty stage.") 610 return 611 } 612 613 if exists := o.IsStageFinished(stageName); exists { 614 log.Warnf("Attempt to add stage (%s) which is already saved.", stageName) 615 return 616 } 617 618 o.FinishedStages = append(o.FinishedStages, stageName) 619 } 620 621 func (o *Operation) IsStageFinished(stage string) bool { 622 for _, value := range o.FinishedStages { 623 if value == stage { 624 return true 625 } 626 } 627 return false 628 } 629 630 type ComponentConfigurationInputList []*gqlschema.ComponentConfigurationInput 631 632 func (l ComponentConfigurationInputList) DeepCopy() []*gqlschema.ComponentConfigurationInput { 633 var copiedList []*gqlschema.ComponentConfigurationInput 634 for _, component := range l { 635 var cpyCfg []*gqlschema.ConfigEntryInput 636 for _, cfg := range component.Configuration { 637 mapped := &gqlschema.ConfigEntryInput{ 638 Key: cfg.Key, 639 Value: cfg.Value, 640 } 641 if cfg.Secret != nil { 642 mapped.Secret = ptr.Bool(*cfg.Secret) 643 } 644 cpyCfg = append(cpyCfg, mapped) 645 } 646 647 copiedList = append(copiedList, &gqlschema.ComponentConfigurationInput{ 648 Component: component.Component, 649 Namespace: component.Namespace, 650 SourceURL: component.SourceURL, 651 Configuration: cpyCfg, 652 }) 653 } 654 return copiedList 655 } 656 657 // KymaComponent represents single Kyma component 658 type KymaComponent struct { 659 Name string `json:"name"` 660 ReleaseName string `json:"release"` 661 Namespace string `json:"namespace"` 662 Source *ComponentSource `json:"source,omitempty"` 663 } 664 665 type ComponentSource struct { 666 URL string `json:"url"` 667 } 668 669 type ConfigForPlan struct { 670 AdditionalComponents []KymaComponent `json:"additional-components" yaml:"additional-components"` 671 KymaTemplate string `json:"kyma-template" yaml:"kyma-template"` 672 } 673 674 func (c *ConfigForPlan) ContainsAdditionalComponent(componentName string) bool { 675 for _, c := range c.AdditionalComponents { 676 fmt.Println(c.Name) 677 if c.Name == componentName { 678 return true 679 } 680 } 681 return false 682 }