github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/process/input/input.go (about) 1 package input 2 3 import ( 4 "fmt" 5 "math/rand" 6 "regexp" 7 "strings" 8 "sync" 9 "time" 10 11 "github.com/kyma-project/kyma-environment-broker/internal/networking" 12 13 "github.com/kyma-project/kyma-environment-broker/internal/ptr" 14 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/internal" 19 "github.com/kyma-project/kyma-environment-broker/internal/broker" 20 "github.com/kyma-project/kyma-environment-broker/internal/runtime" 21 ) 22 23 const ( 24 trialSuffixLength = 5 25 maxRuntimeNameLength = 36 26 ) 27 28 type Config struct { 29 URL string 30 ProvisioningTimeout time.Duration `envconfig:"default=6h"` 31 DeprovisioningTimeout time.Duration `envconfig:"default=5h"` 32 KubernetesVersion string `envconfig:"default=1.16.9"` 33 DefaultGardenerShootPurpose string `envconfig:"default=development"` 34 MachineImage string `envconfig:"optional"` 35 MachineImageVersion string `envconfig:"optional"` 36 TrialNodesNumber int `envconfig:"optional"` 37 DefaultTrialProvider internal.CloudProvider `envconfig:"default=Azure"` // could be: Azure, AWS, GCP, Openstack, unknown 38 OpenstackFloatingPoolName string `envconfig:"default=FloatingIP-external-cp-kyma"` 39 AutoUpdateKubernetesVersion bool `envconfig:"default=false"` 40 AutoUpdateMachineImageVersion bool `envconfig:"default=false"` 41 MultiZoneCluster bool `envconfig:"default=false"` 42 ControlPlaneFailureTolerance string `envconfig:"optional"` 43 } 44 45 type RuntimeInput struct { 46 muOptionalComponents sync.Mutex 47 muLabels sync.Mutex 48 muOverrides sync.Mutex 49 50 provisionRuntimeInput gqlschema.ProvisionRuntimeInput 51 upgradeRuntimeInput gqlschema.UpgradeRuntimeInput 52 upgradeShootInput gqlschema.UpgradeShootInput 53 overrides map[string][]*gqlschema.ConfigEntryInput 54 labels map[string]string 55 globalOverrides []*gqlschema.ConfigEntryInput 56 57 config *internal.ConfigForPlan 58 hyperscalerInputProvider HyperscalerInputProvider 59 optionalComponentsService OptionalComponentService 60 provisioningParameters internal.ProvisioningParameters 61 shootName *string 62 63 componentsDisabler ComponentsDisabler 64 enabledOptionalComponents map[string]struct{} 65 oidcDefaultValues internal.OIDCConfigDTO 66 oidcLastValues gqlschema.OIDCConfigInput 67 68 trialNodesNumber int 69 instanceID string 70 runtimeID string 71 kubeconfig string 72 shootDomain string 73 shootDnsProviders gardener.DNSProvidersData 74 clusterName string 75 modules internal.ModulesDTO 76 } 77 78 func (r *RuntimeInput) Configuration() *internal.ConfigForPlan { 79 return r.config 80 } 81 82 func (r *RuntimeInput) EnableOptionalComponent(componentName string) internal.ProvisionerInputCreator { 83 r.muOptionalComponents.Lock() 84 defer r.muOptionalComponents.Unlock() 85 r.enabledOptionalComponents[componentName] = struct{}{} 86 return r 87 } 88 89 func (r *RuntimeInput) DisableOptionalComponent(componentName string) internal.ProvisionerInputCreator { 90 r.muOptionalComponents.Lock() 91 defer r.muOptionalComponents.Unlock() 92 93 r.optionalComponentsService.AddComponentToDisable(componentName, runtime.NewGenericComponentDisabler(componentName)) 94 delete(r.enabledOptionalComponents, componentName) 95 return r 96 } 97 98 func (r *RuntimeInput) SetProvisioningParameters(params internal.ProvisioningParameters) internal.ProvisionerInputCreator { 99 r.provisioningParameters = params 100 return r 101 } 102 103 func (r *RuntimeInput) SetShootName(name string) internal.ProvisionerInputCreator { 104 r.shootName = &name 105 return r 106 } 107 108 func (r *RuntimeInput) SetShootDomain(name string) internal.ProvisionerInputCreator { 109 r.shootDomain = name 110 return r 111 } 112 113 func (r *RuntimeInput) SetShootDNSProviders(dnsProviders gardener.DNSProvidersData) internal.ProvisionerInputCreator { 114 r.shootDnsProviders = dnsProviders 115 return r 116 } 117 118 func (r *RuntimeInput) SetInstanceID(instanceID string) internal.ProvisionerInputCreator { 119 r.instanceID = instanceID 120 return r 121 } 122 123 func (r *RuntimeInput) SetRuntimeID(runtimeID string) internal.ProvisionerInputCreator { 124 r.runtimeID = runtimeID 125 return r 126 } 127 128 func (r *RuntimeInput) SetKubeconfig(kubeconfig string) internal.ProvisionerInputCreator { 129 r.kubeconfig = kubeconfig 130 return r 131 } 132 133 func (r *RuntimeInput) SetClusterName(name string) internal.ProvisionerInputCreator { 134 if name != "" { 135 r.clusterName = name 136 } 137 return r 138 } 139 140 func (r *RuntimeInput) SetOIDCLastValues(oidcConfig gqlschema.OIDCConfigInput) internal.ProvisionerInputCreator { 141 r.oidcLastValues = oidcConfig 142 return r 143 } 144 145 // SetOverrides sets the overrides for the given component and discard the previous ones. 146 // 147 // Deprecated: use AppendOverrides 148 func (r *RuntimeInput) SetOverrides(component string, overrides []*gqlschema.ConfigEntryInput) internal.ProvisionerInputCreator { 149 // currently same as in AppendOverrides function, as we working on the same underlying object. 150 r.muOverrides.Lock() 151 defer r.muOverrides.Unlock() 152 153 r.overrides[component] = overrides 154 return r 155 } 156 157 // AppendOverrides appends overrides for the given components, the existing overrides are preserved. 158 func (r *RuntimeInput) AppendOverrides(component string, overrides []*gqlschema.ConfigEntryInput) internal.ProvisionerInputCreator { 159 r.muOverrides.Lock() 160 defer r.muOverrides.Unlock() 161 162 for _, o2 := range overrides { 163 found := false 164 for i, o1 := range r.overrides[component] { 165 if o1.Key == o2.Key { 166 found = true 167 r.overrides[component][i].Secret = o2.Secret 168 r.overrides[component][i].Value = o2.Value 169 } 170 } 171 if !found { 172 r.overrides[component] = append(r.overrides[component], o2) 173 } 174 } 175 return r 176 } 177 178 // AppendGlobalOverrides appends overrides, the existing overrides are preserved. 179 func (r *RuntimeInput) AppendGlobalOverrides(overrides []*gqlschema.ConfigEntryInput) internal.ProvisionerInputCreator { 180 r.muOverrides.Lock() 181 defer r.muOverrides.Unlock() 182 183 for _, o2 := range overrides { 184 found := false 185 for i, o1 := range r.globalOverrides { 186 if o1.Key == o2.Key { 187 found = true 188 r.globalOverrides[i].Secret = o2.Secret 189 r.globalOverrides[i].Value = o2.Value 190 } 191 } 192 if !found { 193 r.globalOverrides = append(r.globalOverrides, o2) 194 } 195 } 196 return r 197 } 198 199 func (r *RuntimeInput) SetLabel(key, value string) internal.ProvisionerInputCreator { 200 r.muLabels.Lock() 201 defer r.muLabels.Unlock() 202 203 if r.provisionRuntimeInput.RuntimeInput.Labels == nil { 204 r.provisionRuntimeInput.RuntimeInput.Labels = gqlschema.Labels{} 205 } 206 207 (r.provisionRuntimeInput.RuntimeInput.Labels)[key] = value 208 return r 209 } 210 211 func (r *RuntimeInput) CreateProvisionRuntimeInput() (gqlschema.ProvisionRuntimeInput, error) { 212 for _, step := range []struct { 213 name string 214 execute func() error 215 }{ 216 { 217 name: "applying provisioning parameters customization", 218 execute: r.applyProvisioningParametersForProvisionRuntime, 219 }, 220 { 221 name: "disabling components", 222 execute: r.disableComponentsForProvisionRuntime, 223 }, 224 { 225 name: "disabling optional components that were not selected", 226 execute: r.resolveOptionalComponentsForProvisionRuntime, 227 }, 228 { 229 name: "applying components overrides", 230 execute: r.applyOverridesForProvisionRuntime, 231 }, 232 { 233 name: "applying global overrides", 234 execute: r.applyGlobalOverridesForProvisionRuntime, 235 }, 236 { 237 name: "applying global configuration", 238 execute: r.applyGlobalConfigurationForProvisionRuntime, 239 }, 240 { 241 name: "removing forbidden chars and adding random string to runtime name", 242 execute: r.adjustRuntimeName, 243 }, 244 { 245 name: "set number of nodes from configuration", 246 execute: r.setNodesForTrialProvision, 247 }, 248 { 249 name: "configure OIDC", 250 execute: r.configureOIDC, 251 }, 252 { 253 name: "configure DNS", 254 execute: r.configureDNS, 255 }, 256 { 257 name: "configure networking", 258 execute: r.configureNetworking, 259 }, 260 { 261 name: "configure modules", 262 execute: r.configureModules, 263 }, 264 } { 265 if err := step.execute(); err != nil { 266 return gqlschema.ProvisionRuntimeInput{}, fmt.Errorf("while %s: %w", step.name, err) 267 } 268 } 269 270 return r.provisionRuntimeInput, nil 271 } 272 273 func (r *RuntimeInput) CreateUpgradeRuntimeInput() (gqlschema.UpgradeRuntimeInput, error) { 274 for _, step := range []struct { 275 name string 276 execute func() error 277 }{ 278 { 279 name: "disabling components", 280 execute: r.disableComponentsForUpgradeRuntime, 281 }, 282 { 283 name: "disabling optional components that were not selected", 284 execute: r.resolveOptionalComponentsForUpgradeRuntime, 285 }, 286 { 287 name: "applying components overrides", 288 execute: r.applyOverridesForUpgradeRuntime, 289 }, 290 { 291 name: "applying global overrides", 292 execute: r.applyGlobalOverridesForUpgradeRuntime, 293 }, 294 { 295 name: "applying global configuration", 296 execute: r.applyGlobalConfigurationForUpgradeRuntime, 297 }, 298 { 299 name: "set number of nodes from configuration", 300 execute: r.setNodesForTrialProvision, 301 }, 302 } { 303 if err := step.execute(); err != nil { 304 return gqlschema.UpgradeRuntimeInput{}, fmt.Errorf("while %s: %w", step.name, err) 305 } 306 } 307 308 return r.upgradeRuntimeInput, nil 309 } 310 311 func (r *RuntimeInput) CreateUpgradeShootInput() (gqlschema.UpgradeShootInput, error) { 312 313 for _, step := range []struct { 314 name string 315 execute func() error 316 }{ 317 { 318 name: "applying provisioning parameters customization", 319 execute: r.applyProvisioningParametersForUpgradeShoot, 320 }, 321 { 322 name: "setting number of trial nodes from configuration", 323 execute: r.setNodesForTrialUpgrade, 324 }, 325 { 326 name: "configure OIDC", 327 execute: r.configureOIDC, 328 }, 329 } { 330 if err := step.execute(); err != nil { 331 return gqlschema.UpgradeShootInput{}, fmt.Errorf("while %s: %w", step.name, err) 332 } 333 } 334 return r.upgradeShootInput, nil 335 } 336 337 func (r *RuntimeInput) Provider() internal.CloudProvider { 338 return r.hyperscalerInputProvider.Provider() 339 } 340 341 func (r *RuntimeInput) CreateClusterConfiguration() (reconcilerApi.Cluster, error) { 342 data, err := r.CreateProvisionRuntimeInput() 343 if err != nil { 344 return reconcilerApi.Cluster{}, err 345 } 346 347 if r.runtimeID == "" { 348 return reconcilerApi.Cluster{}, fmt.Errorf("missing runtime ID") 349 } 350 if r.instanceID == "" { 351 return reconcilerApi.Cluster{}, fmt.Errorf("missing instance ID") 352 } 353 if r.shootName == nil { 354 return reconcilerApi.Cluster{}, fmt.Errorf("missing shoot name") 355 } 356 if r.kubeconfig == "" { 357 return reconcilerApi.Cluster{}, fmt.Errorf("missing kubeconfig") 358 } 359 360 var componentConfigs []reconcilerApi.Component 361 for _, cmp := range data.KymaConfig.Components { 362 configs := []reconcilerApi.Configuration{ 363 // because there is no section like global configuration, all "global" settings must 364 // be present in all component configurations. 365 {Key: "global.domainName", Value: r.shootDomain}, 366 } 367 for _, globalCfg := range data.KymaConfig.Configuration { 368 configs = append(configs, reconcilerApi.Configuration{ 369 Key: globalCfg.Key, 370 Value: resolveValueType(globalCfg.Value), 371 Secret: falseIfNil(globalCfg.Secret)}) 372 } 373 374 for _, c := range cmp.Configuration { 375 configuration := reconcilerApi.Configuration{ 376 Key: c.Key, 377 Value: resolveValueType(c.Value), 378 Secret: falseIfNil(c.Secret), 379 } 380 configs = append(configs, configuration) 381 } 382 383 componentConfig := reconcilerApi.Component{ 384 Component: cmp.Component, 385 Namespace: cmp.Namespace, 386 Configuration: configs, 387 } 388 if cmp.SourceURL != nil { 389 componentConfig.URL = *cmp.SourceURL 390 } 391 componentConfigs = append(componentConfigs, componentConfig) 392 } 393 394 result := reconcilerApi.Cluster{ 395 RuntimeID: r.runtimeID, 396 RuntimeInput: reconcilerApi.RuntimeInput{ 397 Name: r.provisionRuntimeInput.RuntimeInput.Name, 398 Description: emptyIfNil(data.RuntimeInput.Description), 399 }, 400 KymaConfig: reconcilerApi.KymaConfig{ 401 Version: r.provisionRuntimeInput.KymaConfig.Version, 402 Profile: string(*data.KymaConfig.Profile), 403 Components: componentConfigs, 404 Administrators: data.ClusterConfig.Administrators, 405 }, 406 Metadata: reconcilerApi.Metadata{ 407 GlobalAccountID: r.provisioningParameters.ErsContext.GlobalAccountID, 408 SubAccountID: r.provisioningParameters.ErsContext.SubAccountID, 409 ServiceID: r.provisioningParameters.ServiceID, 410 ServicePlanID: r.provisioningParameters.PlanID, 411 ServicePlanName: broker.PlanNamesMapping[r.provisioningParameters.PlanID], 412 ShootName: *r.shootName, 413 InstanceID: r.instanceID, 414 }, 415 Kubeconfig: r.kubeconfig, 416 } 417 418 if r.provisionRuntimeInput.ClusterConfig != nil && r.provisionRuntimeInput.ClusterConfig.GardenerConfig != nil { 419 result.Metadata.Region = r.provisionRuntimeInput.ClusterConfig.GardenerConfig.Region 420 } 421 422 return result, nil 423 } 424 425 func emptyIfNil(p *string) string { 426 if p == nil { 427 return "" 428 } 429 return *p 430 } 431 432 func falseIfNil(p *bool) bool { 433 if p == nil { 434 return false 435 } 436 return *p 437 } 438 439 func (r *RuntimeInput) CreateProvisionClusterInput() (gqlschema.ProvisionRuntimeInput, error) { 440 result, err := r.CreateProvisionRuntimeInput() 441 if err != nil { 442 return gqlschema.ProvisionRuntimeInput{}, nil 443 } 444 result.KymaConfig = nil 445 return result, nil 446 } 447 448 func (r *RuntimeInput) applyProvisioningParametersForProvisionRuntime() error { 449 params := r.provisioningParameters.Parameters 450 updateString(&r.provisionRuntimeInput.RuntimeInput.Name, ¶ms.Name) 451 452 if r.provisioningParameters.PlanID == broker.OwnClusterPlanID { 453 return nil 454 } 455 456 updateInt(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.MaxUnavailable, params.MaxUnavailable) 457 updateInt(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.MaxSurge, params.MaxSurge) 458 updateInt(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.AutoScalerMin, params.AutoScalerMin) 459 updateInt(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.AutoScalerMax, params.AutoScalerMax) 460 updateInt(r.provisionRuntimeInput.ClusterConfig.GardenerConfig.VolumeSizeGb, params.VolumeSizeGb) 461 updateString(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.Name, r.shootName) 462 if params.Region != nil && *params.Region != "" { 463 updateString(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.Region, params.Region) 464 } 465 updateString(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.MachineType, params.MachineType) 466 updateString(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.TargetSecret, params.TargetSecret) 467 updateString(r.provisionRuntimeInput.ClusterConfig.GardenerConfig.Purpose, params.Purpose) 468 if params.LicenceType != nil { 469 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.LicenceType = params.LicenceType 470 } 471 472 // admins parameter check 473 if len(r.provisioningParameters.Parameters.RuntimeAdministrators) == 0 { 474 // default admin set from UserID in ERSContext 475 r.provisionRuntimeInput.ClusterConfig.Administrators = []string{r.provisioningParameters.ErsContext.UserID} 476 } else { 477 // set admins for new runtime 478 r.provisionRuntimeInput.ClusterConfig.Administrators = []string{} 479 r.provisionRuntimeInput.ClusterConfig.Administrators = append( 480 r.provisionRuntimeInput.ClusterConfig.Administrators, 481 r.provisioningParameters.Parameters.RuntimeAdministrators..., 482 ) 483 } 484 485 r.hyperscalerInputProvider.ApplyParameters(r.provisionRuntimeInput.ClusterConfig, r.provisioningParameters) 486 487 return nil 488 } 489 490 func (r *RuntimeInput) applyProvisioningParametersForUpgradeShoot() error { 491 if len(r.provisioningParameters.Parameters.RuntimeAdministrators) != 0 { 492 // prepare new admins list for existing runtime 493 newAdministrators := make([]string, 0, len(r.provisioningParameters.Parameters.RuntimeAdministrators)) 494 newAdministrators = append(newAdministrators, r.provisioningParameters.Parameters.RuntimeAdministrators...) 495 r.upgradeShootInput.Administrators = newAdministrators 496 } else { 497 if r.provisioningParameters.ErsContext.UserID != "" { 498 // get default admin (user_id from provisioning operation) 499 r.upgradeShootInput.Administrators = []string{r.provisioningParameters.ErsContext.UserID} 500 } else { 501 // some old clusters does not have an user_id 502 r.upgradeShootInput.Administrators = []string{} 503 } 504 } 505 506 updateInt(r.upgradeShootInput.GardenerConfig.MaxSurge, r.provisioningParameters.Parameters.MaxSurge) 507 updateInt(r.upgradeShootInput.GardenerConfig.MaxUnavailable, r.provisioningParameters.Parameters.MaxUnavailable) 508 509 return nil 510 } 511 512 func (r *RuntimeInput) resolveOptionalComponentsForProvisionRuntime() error { 513 r.muOptionalComponents.Lock() 514 defer r.muOptionalComponents.Unlock() 515 516 componentsToInstall := []string{} 517 componentsToInstall = append(componentsToInstall, r.provisioningParameters.Parameters.OptionalComponentsToInstall...) 518 for name := range r.enabledOptionalComponents { 519 componentsToInstall = append(componentsToInstall, name) 520 } 521 toDisable := r.optionalComponentsService.ComputeComponentsToDisable(componentsToInstall) 522 523 filterOut, err := r.optionalComponentsService.ExecuteDisablers(r.provisionRuntimeInput.KymaConfig.Components, toDisable...) 524 if err != nil { 525 return fmt.Errorf("while disabling components %v: %w", toDisable, err) 526 } 527 528 r.provisionRuntimeInput.KymaConfig.Components = filterOut 529 530 return nil 531 } 532 533 func (r *RuntimeInput) resolveOptionalComponentsForUpgradeRuntime() error { 534 r.muOptionalComponents.Lock() 535 defer r.muOptionalComponents.Unlock() 536 537 componentsToInstall := []string{} 538 componentsToInstall = append(componentsToInstall, r.provisioningParameters.Parameters.OptionalComponentsToInstall...) 539 for name := range r.enabledOptionalComponents { 540 componentsToInstall = append(componentsToInstall, name) 541 } 542 toDisable := r.optionalComponentsService.ComputeComponentsToDisable(componentsToInstall) 543 544 filterOut, err := r.optionalComponentsService.ExecuteDisablers(r.upgradeRuntimeInput.KymaConfig.Components, toDisable...) 545 if err != nil { 546 return fmt.Errorf("while disabling components %v: %w", toDisable, err) 547 } 548 549 r.upgradeRuntimeInput.KymaConfig.Components = filterOut 550 551 return nil 552 } 553 554 func (r *RuntimeInput) disableComponentsForProvisionRuntime() error { 555 filterOut, err := r.componentsDisabler.DisableComponents(r.provisionRuntimeInput.KymaConfig.Components) 556 if err != nil { 557 return err 558 } 559 560 r.provisionRuntimeInput.KymaConfig.Components = filterOut 561 562 return nil 563 } 564 565 func (r *RuntimeInput) disableComponentsForUpgradeRuntime() error { 566 filterOut, err := r.componentsDisabler.DisableComponents(r.upgradeRuntimeInput.KymaConfig.Components) 567 if err != nil { 568 return err 569 } 570 571 r.upgradeRuntimeInput.KymaConfig.Components = filterOut 572 573 return nil 574 } 575 576 func (r *RuntimeInput) applyOverridesForProvisionRuntime() error { 577 for i := range r.provisionRuntimeInput.KymaConfig.Components { 578 if entry, found := r.overrides[r.provisionRuntimeInput.KymaConfig.Components[i].Component]; found { 579 r.provisionRuntimeInput.KymaConfig.Components[i].Configuration = []*gqlschema.ConfigEntryInput{} 580 r.provisionRuntimeInput.KymaConfig.Components[i].Configuration = append(r.provisionRuntimeInput.KymaConfig.Components[i].Configuration, entry...) 581 } 582 } 583 584 return nil 585 } 586 587 func (r *RuntimeInput) applyOverridesForUpgradeRuntime() error { 588 for i := range r.upgradeRuntimeInput.KymaConfig.Components { 589 if entry, found := r.overrides[r.upgradeRuntimeInput.KymaConfig.Components[i].Component]; found { 590 r.upgradeRuntimeInput.KymaConfig.Components[i].Configuration = []*gqlschema.ConfigEntryInput{} 591 r.upgradeRuntimeInput.KymaConfig.Components[i].Configuration = append(r.upgradeRuntimeInput.KymaConfig.Components[i].Configuration, entry...) 592 } 593 } 594 595 return nil 596 } 597 598 func (r *RuntimeInput) applyGlobalOverridesForProvisionRuntime() error { 599 r.provisionRuntimeInput.KymaConfig.Configuration = r.globalOverrides 600 return nil 601 } 602 603 func (r *RuntimeInput) applyGlobalOverridesForUpgradeRuntime() error { 604 r.upgradeRuntimeInput.KymaConfig.Configuration = r.globalOverrides 605 return nil 606 } 607 608 func (r *RuntimeInput) applyGlobalConfigurationForProvisionRuntime() error { 609 strategy := gqlschema.ConflictStrategyReplace 610 r.provisionRuntimeInput.KymaConfig.ConflictStrategy = &strategy 611 return nil 612 } 613 614 func (r *RuntimeInput) applyGlobalConfigurationForUpgradeRuntime() error { 615 strategy := gqlschema.ConflictStrategyReplace 616 r.upgradeRuntimeInput.KymaConfig.ConflictStrategy = &strategy 617 return nil 618 } 619 620 func (r *RuntimeInput) adjustRuntimeName() error { 621 // if the cluster name was created before, it must be used instead of generating one 622 if r.clusterName != "" { 623 r.provisionRuntimeInput.RuntimeInput.Name = r.clusterName 624 return nil 625 } 626 627 reg, err := regexp.Compile("[^a-zA-Z0-9\\-\\.]+") 628 if err != nil { 629 return fmt.Errorf("while compiling regexp: %w", err) 630 } 631 632 name := strings.ToLower(reg.ReplaceAllString(r.provisionRuntimeInput.RuntimeInput.Name, "")) 633 modifiedLength := len(name) + trialSuffixLength + 1 634 if modifiedLength > maxRuntimeNameLength { 635 name = trimLastCharacters(name, modifiedLength-maxRuntimeNameLength) 636 } 637 638 r.provisionRuntimeInput.RuntimeInput.Name = fmt.Sprintf("%s-%s", name, randomString(trialSuffixLength)) 639 return nil 640 } 641 642 func (r *RuntimeInput) configureDNS() error { 643 dnsParamsToSet := gqlschema.DNSConfigInput{} 644 645 // if dns providers is given 646 if len(r.shootDnsProviders.Providers) != 0 { 647 for _, v := range r.shootDnsProviders.Providers { 648 dnsParamsToSet.Providers = append(dnsParamsToSet.Providers, &gqlschema.DNSProviderInput{ 649 DomainsInclude: v.DomainsInclude, 650 Primary: v.Primary, 651 SecretName: v.SecretName, 652 Type: v.Type, 653 }) 654 } 655 } 656 657 dnsParamsToSet.Domain = r.shootDomain 658 659 if r.provisionRuntimeInput.ClusterConfig != nil && 660 r.provisionRuntimeInput.ClusterConfig.GardenerConfig != nil { 661 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.DNSConfig = &dnsParamsToSet 662 } 663 664 return nil 665 } 666 667 func (r *RuntimeInput) configureOIDC() error { 668 // set default or provided params to provisioning/update input (if exists) 669 // This method could be used for: 670 // provisioning (upgradeShootInput.GardenerConfig is nil) 671 // or upgrade (provisionRuntimeInput.ClusterConfig is nil) 672 673 if r.provisionRuntimeInput.ClusterConfig != nil { 674 oidcParamsToSet := r.setOIDCForProvisioning() 675 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.OidcConfig = oidcParamsToSet 676 } 677 if r.upgradeShootInput.GardenerConfig != nil { 678 oidcParamsToSet := r.setOIDCForUpgrade() 679 r.upgradeShootInput.GardenerConfig.OidcConfig = oidcParamsToSet 680 } 681 return nil 682 } 683 684 func (r *RuntimeInput) configureNetworking() error { 685 if r.provisioningParameters.Parameters.Networking == nil { 686 return nil 687 } 688 updateString(&r.provisionRuntimeInput.ClusterConfig.GardenerConfig.WorkerCidr, 689 &r.provisioningParameters.Parameters.Networking.NodesCidr) 690 691 // if the Networking section is set, then 692 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.PodsCidr = ptr.String(networking.DefaultPodsCIDR) 693 updateString(r.provisionRuntimeInput.ClusterConfig.GardenerConfig.PodsCidr, 694 r.provisioningParameters.Parameters.Networking.PodsCidr) 695 696 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.ServicesCidr = ptr.String(networking.DefaultServicesCIDR) 697 updateString(r.provisionRuntimeInput.ClusterConfig.GardenerConfig.ServicesCidr, 698 r.provisioningParameters.Parameters.Networking.ServicesCidr) 699 700 return nil 701 } 702 703 func (r *RuntimeInput) setNodesForTrialProvision() error { 704 // parameter with number of notes for trial plan is optional; if parameter is not set value is equal to 0 705 if r.trialNodesNumber == 0 { 706 return nil 707 } 708 if broker.IsTrialPlan(r.provisioningParameters.PlanID) { 709 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.AutoScalerMin = r.trialNodesNumber 710 r.provisionRuntimeInput.ClusterConfig.GardenerConfig.AutoScalerMax = r.trialNodesNumber 711 } 712 return nil 713 } 714 715 func (r *RuntimeInput) setNodesForTrialUpgrade() error { 716 // parameter with number of nodes for trial plan is optional; if parameter is not set value is equal to 0 717 if r.trialNodesNumber == 0 { 718 return nil 719 } 720 if broker.IsTrialPlan(r.provisioningParameters.PlanID) { 721 r.upgradeShootInput.GardenerConfig.AutoScalerMin = &r.trialNodesNumber 722 r.upgradeShootInput.GardenerConfig.AutoScalerMax = &r.trialNodesNumber 723 } 724 return nil 725 } 726 727 func (r *RuntimeInput) setOIDCForProvisioning() *gqlschema.OIDCConfigInput { 728 oidcConfig := &gqlschema.OIDCConfigInput{ 729 ClientID: r.oidcDefaultValues.ClientID, 730 GroupsClaim: r.oidcDefaultValues.GroupsClaim, 731 IssuerURL: r.oidcDefaultValues.IssuerURL, 732 SigningAlgs: r.oidcDefaultValues.SigningAlgs, 733 UsernameClaim: r.oidcDefaultValues.UsernameClaim, 734 UsernamePrefix: r.oidcDefaultValues.UsernamePrefix, 735 } 736 737 if r.provisioningParameters.Parameters.OIDC.IsProvided() { 738 r.setOIDCFromProvisioningParameters(oidcConfig) 739 } 740 741 return oidcConfig 742 } 743 744 func (r *RuntimeInput) setOIDCForUpgrade() *gqlschema.OIDCConfigInput { 745 oidcConfig := r.oidcLastValues 746 r.setOIDCDefaultValuesIfEmpty(&oidcConfig) 747 748 if r.provisioningParameters.Parameters.OIDC.IsProvided() { 749 r.setOIDCFromProvisioningParameters(&oidcConfig) 750 } 751 752 return &oidcConfig 753 } 754 755 func (r *RuntimeInput) setOIDCFromProvisioningParameters(oidcConfig *gqlschema.OIDCConfigInput) { 756 providedOIDC := r.provisioningParameters.Parameters.OIDC 757 oidcConfig.ClientID = providedOIDC.ClientID 758 oidcConfig.IssuerURL = providedOIDC.IssuerURL 759 if len(providedOIDC.GroupsClaim) != 0 { 760 oidcConfig.GroupsClaim = providedOIDC.GroupsClaim 761 } 762 if len(providedOIDC.SigningAlgs) != 0 { 763 oidcConfig.SigningAlgs = providedOIDC.SigningAlgs 764 } 765 if len(providedOIDC.UsernameClaim) != 0 { 766 oidcConfig.UsernameClaim = providedOIDC.UsernameClaim 767 } 768 if len(providedOIDC.UsernamePrefix) != 0 { 769 oidcConfig.UsernamePrefix = providedOIDC.UsernamePrefix 770 } 771 } 772 773 func (r *RuntimeInput) setOIDCDefaultValuesIfEmpty(oidcConfig *gqlschema.OIDCConfigInput) { 774 if oidcConfig.ClientID == "" { 775 oidcConfig.ClientID = r.oidcDefaultValues.ClientID 776 } 777 if oidcConfig.IssuerURL == "" { 778 oidcConfig.IssuerURL = r.oidcDefaultValues.IssuerURL 779 } 780 if oidcConfig.GroupsClaim == "" { 781 oidcConfig.GroupsClaim = r.oidcDefaultValues.GroupsClaim 782 } 783 if len(oidcConfig.SigningAlgs) == 0 { 784 oidcConfig.SigningAlgs = r.oidcDefaultValues.SigningAlgs 785 } 786 if oidcConfig.UsernameClaim == "" { 787 oidcConfig.UsernameClaim = r.oidcDefaultValues.UsernameClaim 788 } 789 if oidcConfig.UsernamePrefix == "" { 790 oidcConfig.UsernamePrefix = r.oidcDefaultValues.UsernamePrefix 791 } 792 } 793 794 func (r *RuntimeInput) configureModules() error { 795 if r.provisioningParameters.Parameters.Modules != nil { 796 r.modules = *r.provisioningParameters.Parameters.Modules 797 } 798 return nil 799 } 800 801 func updateString(toUpdate *string, value *string) { 802 if value != nil { 803 *toUpdate = *value 804 } 805 } 806 807 func updateInt(toUpdate *int, value *int) { 808 if value != nil { 809 *toUpdate = *value 810 } 811 } 812 813 func randomString(n int) string { 814 var letters = []rune("abcdefghijklmnopqrstuvwxyz") 815 816 b := make([]rune, n) 817 for i := range b { 818 b[i] = letters[rand.Intn(len(letters))] 819 } 820 return string(b) 821 } 822 823 func trimLastCharacters(s string, count int) string { 824 s = s[:len(s)-count] 825 return s 826 } 827 828 func resolveValueType(v interface{}) interface{} { 829 // this is a workaround. Finally we have to obtain the type during the reading overrides 830 var val interface{} 831 switch v { 832 case "true": 833 val = true 834 case "false": 835 val = false 836 default: 837 val = v 838 } 839 840 return val 841 }