Skip to content

Commit

Permalink
KIM Integration - SAP Converged Cloud provider (#990)
Browse files Browse the repository at this point in the history
* initial version - no failure handling

failure tolerance handled on another level

tests started but not finished

tests added

* go imports

---------

Co-authored-by: Piotr Miśkiewicz <[email protected]>
  • Loading branch information
jaroslaw-pieszka and piotrmiskiewicz authored Aug 7, 2024
1 parent d4e1b3f commit 7ab8588
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,11 @@ func (s *CreateRuntimeResourceStep) providerValues(operation *internal.Operation
default:
return provider.Values{}, fmt.Errorf("freemium provider for '%s' is not supported", operation.ProvisioningParameters.PlatformProvider)
}

case broker.SapConvergedCloudPlanID:
p = &provider.SapConvergedCloudInputProvider{
MultiZone: s.config.MultiZoneCluster,
ProvisioningParameters: operation.ProvisioningParameters,
}
case broker.TrialPlanID:
var trialProvider internal.CloudProvider
if operation.ProvisioningParameters.Parameters.Provider == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,58 @@ func TestCreateRuntimeResourceStep_Defaults_GCP_MultiZone_ActualCreation(t *test
assert.NoError(t, err)
}

func TestCreateRuntimeResourceStep_SapConvergedCloud(t *testing.T) {

for _, testCase := range []struct {
name string
gotProvider internal.CloudProvider
expectedZonesCount int
expectedProvider string
expectedMachineType string
expectedRegion string
possibleZones []string
}{
{"Single zone", internal.SapConvergedCloud, 1, "openstack", "g_c2_m8", "eu-de-1", []string{"eu-de-1a", "eu-de-1b", "eu-de-1d"}},
{"Multi zone", internal.SapConvergedCloud, 3, "openstack", "g_c2_m8", "eu-de-1", []string{"eu-de-1a", "eu-de-1b", "eu-de-1d"}},
} {
t.Run(testCase.name, func(t *testing.T) {
log := logrus.New()
memoryStorage := storage.NewMemoryStorage()
err := imv1.AddToScheme(scheme.Scheme)
assert.NoError(t, err)
instance, operation := fixInstanceAndOperation(broker.SapConvergedCloudPlanID, "", "platform-region")
operation.ProvisioningParameters.PlatformProvider = testCase.gotProvider
assertInsertions(t, memoryStorage, instance, operation)
kimConfig := fixKimConfig("sap-converged-cloud", false)

cli := getClientForTests(t)
inputConfig := input.Config{MultiZoneCluster: testCase.expectedZonesCount > 1}
step := NewCreateRuntimeResourceStep(memoryStorage.Operations(), memoryStorage.Instances(), cli, kimConfig, inputConfig, nil, false)

// when
entry := log.WithFields(logrus.Fields{"step": "TEST"})
gotOperation, repeat, err := step.Run(operation, entry)

// then
assert.NoError(t, err)
assert.Zero(t, repeat)
assert.Equal(t, domain.InProgress, gotOperation.State)

runtime := imv1.Runtime{}
err = cli.Get(context.Background(), client.ObjectKey{
Namespace: "kyma-system",
Name: operation.RuntimeID,
}, &runtime)
assert.NoError(t, err)
assert.Equal(t, operation.RuntimeID, runtime.Name)
assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"])
assert.Equal(t, testCase.expectedProvider, runtime.Spec.Shoot.Provider.Type)
assertWorkers(t, runtime.Spec.Shoot.Provider.Workers, testCase.expectedMachineType, 20, 3, testCase.expectedZonesCount, 0, testCase.expectedZonesCount, testCase.possibleZones)

})
}
}

func TestCreateRuntimeResourceStep_Defaults_Freemium(t *testing.T) {

for _, testCase := range []struct {
Expand Down Expand Up @@ -699,7 +751,6 @@ func TestCreateRuntimeResourceStep_Defaults_Freemium(t *testing.T) {

})
}

}

// assertions
Expand Down
53 changes: 53 additions & 0 deletions internal/provider/sap-converged-cloud.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package provider

import (
"github.com/kyma-project/kyma-environment-broker/internal"
)

const (
DefaultSapConvergedCloudRegion = "eu-de-1"
DefaultSapConvergedCloudMachineType = "g_c2_m8"
DefaultSapConvergedCloudMultiZoneCount = 3
)

type (
SapConvergedCloudInputProvider struct {
MultiZone bool
ProvisioningParameters internal.ProvisioningParameters
}
)

func (p *SapConvergedCloudInputProvider) Provide() Values {
zonesCount := p.zonesCount()
zones := p.zones()
region := DefaultSapConvergedCloudRegion
if p.ProvisioningParameters.Parameters.Region != nil {
region = *p.ProvisioningParameters.Parameters.Region
}
return Values{
DefaultAutoScalerMax: 20,
DefaultAutoScalerMin: 3,
ZonesCount: zonesCount,
Zones: zones,
ProviderType: "openstack",
DefaultMachineType: DefaultSapConvergedCloudMachineType,
Region: region,
Purpose: PurposeProduction,
}
}

func (p *SapConvergedCloudInputProvider) zonesCount() int {
zonesCount := 1
if p.MultiZone {
zonesCount = DefaultSapConvergedCloudMultiZoneCount
}
return zonesCount
}

func (p *SapConvergedCloudInputProvider) zones() []string {
region := DefaultSapConvergedCloudRegion
if p.ProvisioningParameters.Parameters.Region != nil {
region = *p.ProvisioningParameters.Parameters.Region
}
return ZonesForSapConvergedCloud(region, p.zonesCount())
}
45 changes: 0 additions & 45 deletions internal/provider/sap-converged-cloud_provider.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
package provider

import (
"fmt"
"math/rand"
"strings"

"github.com/kyma-project/control-plane/components/provisioner/pkg/gqlschema"

"github.com/kyma-project/kyma-environment-broker/internal"
"github.com/kyma-project/kyma-environment-broker/internal/networking"
)

const (
DefaultSapConvergedCloudRegion = "eu-de-1"
DefaultSapConvergedCloudMachineType = "g_c2_m8"
DefaultSapConvergedCloudMultiZoneCount = 3
)

type SapConvergedCloudInput struct {
MultiZone bool
ControlPlaneFailureTolerance string
Expand Down Expand Up @@ -71,38 +61,3 @@ func (p *SapConvergedCloudInput) Profile() gqlschema.KymaProfile {
func (p *SapConvergedCloudInput) Provider() internal.CloudProvider {
return internal.SapConvergedCloud
}

// sapConvergedCloudZones defines a possible suffixes for given OpenStack regions
// The table is tested in a unit test to check if all necessary regions are covered
var sapConvergedCloudZones = map[string]string{
"eu-de-1": "abd",
"ap-au-1": "ab",
"na-us-1": "abd",
"eu-de-2": "ab",
"na-us-2": "ab",
"ap-jp-1": "a",
"ap-ae-1": "ab",
}

func ZonesForSapConvergedCloud(region string, zonesCount int) []string {
zones, found := sapConvergedCloudZones[region]
if !found {
zones = "a"
zonesCount = 1
}

availableZones := strings.Split(zones, "")
rand.Shuffle(len(availableZones), func(i, j int) { availableZones[i], availableZones[j] = availableZones[j], availableZones[i] })
if zonesCount > len(availableZones) {
// get maximum number of zones for region
zonesCount = len(availableZones)
}

availableZones = availableZones[:zonesCount]

var generatedZones []string
for _, zone := range availableZones {
generatedZones = append(generatedZones, fmt.Sprintf("%s%s", region, zone))
}
return generatedZones
}
79 changes: 0 additions & 79 deletions internal/provider/sap-converged-cloud_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,82 +17,3 @@ func TestZonesForSapConvergedCloudZones(t *testing.T) {
_, exists := sapConvergedCloudZones[DefaultSapConvergedCloudRegion]
assert.True(t, exists)
}

func TestMultipleZonesForSapConvergedCloudRegion(t *testing.T) {
for tname, tcase := range map[string]struct {
region string
zonesCount int
}{
"for valid zonesCount in eu-de-1": {
region: "eu-de-1",
zonesCount: 3,
},
"for valid zonesCount in ap-au-1": {
region: "ap-au-1",
zonesCount: 2,
},
"for valid zonesCount in na-us-1": {
region: "na-us-1",
zonesCount: 3,
},
"for valid zonesCount in eu-de-2": {
region: "eu-de-2",
zonesCount: 2,
},
"for valid zonesCount in na-us-2": {
region: "na-us-2",
zonesCount: 2,
},
"for valid zonesCount in ap-jp-1": {
region: "ap-jp-1",
zonesCount: 1,
},
"for valid zonesCount in ap-ae-1": {
region: "ap-ae-1",
zonesCount: 2,
},
} {
t.Run(tname, func(t *testing.T) {
// when
generatedZones := ZonesForSapConvergedCloud(tcase.region, tcase.zonesCount)

// then
for _, zone := range generatedZones {
regionFromZone := zone[:len(zone)-1]
assert.Equal(t, tcase.region, regionFromZone)
}
assert.Equal(t, tcase.zonesCount, len(generatedZones))
// check if all zones are unique
assert.Condition(t, func() (success bool) {
var zones []string
for _, zone := range generatedZones {
for _, z := range zones {
if zone == z {
return false
}
}
zones = append(zones, zone)
}
return true
})
})
}

t.Run("for zonesCount exceeding maximum zones for region", func(t *testing.T) {
// given
region := "eu-de-1"
zonesCountExceedingMaximum := 20
maximumZonesForRegion := len(sapConvergedCloudZones[region])
// "eu-de-1" region has maximum 3 zones, user request 20

// when
generatedZones := ZonesForSapConvergedCloud(region, zonesCountExceedingMaximum)

// then
for _, zone := range generatedZones {
regionFromZone := zone[:len(zone)-1]
assert.Equal(t, region, regionFromZone)
}
assert.Equal(t, maximumZonesForRegion, len(generatedZones))
})
}
35 changes: 35 additions & 0 deletions internal/provider/zones.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,38 @@ func MultipleZonesForAWSRegion(region string, zonesCount int) []string {
}
return generatedZones
}

// sapConvergedCloudZones defines a possible suffixes for given OpenStack regions
// The table is tested in a unit test to check if all necessary regions are covered
var sapConvergedCloudZones = map[string]string{
"eu-de-1": "abd",
"ap-au-1": "ab",
"na-us-1": "abd",
"eu-de-2": "ab",
"na-us-2": "ab",
"ap-jp-1": "a",
"ap-ae-1": "ab",
}

func ZonesForSapConvergedCloud(region string, zonesCount int) []string {
zones, found := sapConvergedCloudZones[region]
if !found {
zones = "a"
zonesCount = 1
}

availableZones := strings.Split(zones, "")
rand.Shuffle(len(availableZones), func(i, j int) { availableZones[i], availableZones[j] = availableZones[j], availableZones[i] })
if zonesCount > len(availableZones) {
// get maximum number of zones for region
zonesCount = len(availableZones)
}

availableZones = availableZones[:zonesCount]

var generatedZones []string
for _, zone := range availableZones {
generatedZones = append(generatedZones, fmt.Sprintf("%s%s", region, zone))
}
return generatedZones
}
Loading

0 comments on commit 7ab8588

Please sign in to comment.