diff --git a/internal/process/provisioning/create_runtime_resource_step.go b/internal/process/provisioning/create_runtime_resource_step.go index 60c69980cf..ea2b87f2ca 100644 --- a/internal/process/provisioning/create_runtime_resource_step.go +++ b/internal/process/provisioning/create_runtime_resource_step.go @@ -3,6 +3,7 @@ package provisioning import ( "context" "fmt" + "reflect" "strconv" "time" @@ -179,7 +180,8 @@ func (s *CreateRuntimeResourceStep) createSecurityConfiguration(operation intern security.Administrators = operation.ProvisioningParameters.Parameters.RuntimeAdministrators } - security.Networking.Filter.Egress.Enabled = false + security.Networking.Filter.Egress.Enabled = *operation.ProvisioningParameters.ErsContext.DisableEnterprisePolicyFilter() + // Ingress is not supported yet, nevertheless we set it for completeness security.Networking.Filter.Ingress = &imv1.Ingress{Enabled: false} return security @@ -331,15 +333,10 @@ func (s *CreateRuntimeResourceStep) createNetworkingConfiguration(operation inte networkingParams = &internal.NetworkingDTO{} } - nodes := networkingParams.NodesCidr - if nodes == "" { - nodes = networking.DefaultNodesCIDR - } - return imv1.Networking{ Pods: DefaultIfParamNotSet(networking.DefaultPodsCIDR, networkingParams.PodsCidr), Services: DefaultIfParamNotSet(networking.DefaultServicesCIDR, networkingParams.ServicesCidr), - Nodes: nodes, + Nodes: DefaultIfParamZero(networking.DefaultNodesCIDR, networkingParams.NodesCidr), } } @@ -356,6 +353,7 @@ func (s *CreateRuntimeResourceStep) getEmptyOrExistingRuntimeResource(name, name return &runtime, nil } +// TODO unit test func (s *CreateRuntimeResourceStep) createKubernetesConfiguration(operation internal.Operation) imv1.Kubernetes { oidc := gardener.OIDCConfig{ ClientID: &s.oidcDefaultValues.ClientID, @@ -366,24 +364,12 @@ func (s *CreateRuntimeResourceStep) createKubernetesConfiguration(operation inte UsernamePrefix: &s.oidcDefaultValues.UsernamePrefix, } if operation.ProvisioningParameters.Parameters.OIDC != nil { - if operation.ProvisioningParameters.Parameters.OIDC.ClientID != "" { - oidc.ClientID = &operation.ProvisioningParameters.Parameters.OIDC.ClientID - } - if operation.ProvisioningParameters.Parameters.OIDC.GroupsClaim != "" { - oidc.GroupsClaim = &operation.ProvisioningParameters.Parameters.OIDC.GroupsClaim - } - if operation.ProvisioningParameters.Parameters.OIDC.IssuerURL != "" { - oidc.IssuerURL = &operation.ProvisioningParameters.Parameters.OIDC.IssuerURL - } - if len(operation.ProvisioningParameters.Parameters.OIDC.SigningAlgs) > 0 { - oidc.SigningAlgs = operation.ProvisioningParameters.Parameters.OIDC.SigningAlgs - } - if operation.ProvisioningParameters.Parameters.OIDC.UsernameClaim != "" { - oidc.UsernameClaim = &operation.ProvisioningParameters.Parameters.OIDC.UsernameClaim - } - if operation.ProvisioningParameters.Parameters.OIDC.UsernamePrefix != "" { - oidc.UsernamePrefix = &operation.ProvisioningParameters.Parameters.OIDC.UsernamePrefix - } + oidc.SigningAlgs = DefaultIfParamZero(oidc.SigningAlgs, operation.ProvisioningParameters.Parameters.OIDC.SigningAlgs) + oidc.ClientID = DefaultIfParamZero(oidc.ClientID, &operation.ProvisioningParameters.Parameters.OIDC.ClientID) + oidc.GroupsClaim = DefaultIfParamZero(oidc.GroupsClaim, &operation.ProvisioningParameters.Parameters.OIDC.GroupsClaim) + oidc.IssuerURL = DefaultIfParamZero(oidc.IssuerURL, &operation.ProvisioningParameters.Parameters.OIDC.IssuerURL) + oidc.UsernameClaim = DefaultIfParamZero(oidc.UsernameClaim, &operation.ProvisioningParameters.Parameters.OIDC.UsernameClaim) + oidc.UsernamePrefix = DefaultIfParamZero(oidc.UsernamePrefix, &operation.ProvisioningParameters.Parameters.OIDC.UsernamePrefix) } return imv1.Kubernetes{ @@ -402,6 +388,14 @@ func DefaultIfParamNotSet[T interface{}](d T, param *T) T { return *param } +func DefaultIfParamZero[T interface{}](d T, param T) T { + field := reflect.ValueOf(param) + if field.IsZero() { + return d + } + return param +} + func RuntimeToYaml(runtime *imv1.Runtime) (string, error) { result, err := yaml.Marshal(runtime) if err != nil { diff --git a/internal/process/provisioning/create_runtime_resource_step_test.go b/internal/process/provisioning/create_runtime_resource_step_test.go index 87e514d4d6..ec83fc289e 100644 --- a/internal/process/provisioning/create_runtime_resource_step_test.go +++ b/internal/process/provisioning/create_runtime_resource_step_test.go @@ -166,89 +166,57 @@ func TestCreateRuntimeResourceStep_AllYamls(t *testing.T) { // Actual creation tests -func TestCreateRuntimeResourceStep_ActualCreation(t *testing.T) { +func TestCreateRuntimeResourceStep_Defaults_AWS_SingleZone_EnforceSeed_ActualCreation(t *testing.T) { + // given + log := logrus.New() + memoryStorage := storage.NewMemoryStorage() - for _, testCase := range []struct { - name string - providerType string - planID string - multiZone bool - region string - purpose string - machine string - maximum int - minimum int - maxSurge int - maxUnavailable int - zonesCount int - zones []string - }{ - {"GCP Multi Zone", "gcp", broker.GCPPlanID, true, "asia-south1", "production", "n2-standard-2", - 20, 3, 3, 0, 3, []string{"asia-south1-a", "asia-south1-b", "asia-south1-c"}}, - {"GCP Single Zone", "gcp", broker.GCPPlanID, false, "asia-south1", "production", "n2-standard-2", - 20, 3, 1, 0, 1, []string{"asia-south1-a", "asia-south1-b", "asia-south1-c"}}, - {"Azure Multi Zone", "azure", broker.AzurePlanID, true, "westeurope", "production", "Standard_D2s_v5", - 20, 3, 3, 0, 3, []string{"1", "2", "3"}}, - {"Azure Single Zone", "azure", broker.AzurePlanID, false, "westeurope", "production", "Standard_D2s_v5", - 20, 3, 1, 0, 1, []string{"1", "2", "3"}}, - {"Azure Lite", "azure", broker.AzureLitePlanID, false, "westeurope", "evaluation", "Standard_D4s_v5", - 10, 2, 1, 0, 1, []string{"1", "2", "3"}}, - {"Preview Multi Zone", "aws", broker.PreviewPlanID, true, "eu-west-2", "production", "m6i.large", - 20, 3, 3, 0, 3, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}}, - {"Preview Single Zone", "aws", broker.PreviewPlanID, false, "eu-west-2", "production", "m6i.large", - 20, 3, 1, 0, 1, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}}, - {"AWS Multi Zone", "aws", broker.AWSPlanID, true, "eu-west-2", "production", "m6i.large", - 20, 3, 3, 0, 3, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}}, - {"AWS Single Zone", "aws", broker.AWSPlanID, false, "eu-west-2", "production", "m6i.large", - 20, 3, 1, 0, 1, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}}, - } { - t.Run(testCase.name, func(t *testing.T) { - // given - log := logrus.New() - memoryStorage := storage.NewMemoryStorage() - err := imv1.AddToScheme(scheme.Scheme) + err := imv1.AddToScheme(scheme.Scheme) - instance, operation := fixInstanceAndOperation(testCase.planID, testCase.region, "platform-region") - assertInsertions(t, memoryStorage, instance, operation) + instance, operation := fixInstanceAndOperation(broker.AWSPlanID, "eu-west-2", "platform-region") + operation.ProvisioningParameters.Parameters.ShootAndSeedSameRegion = ptr.Bool(true) + assertInsertions(t, memoryStorage, instance, operation) - kimConfig := fixKimConfigWithAllPlans(false) + kimConfig := fixKimConfig("aws", false) + inputConfig := input.Config{MultiZoneCluster: false, ControlPlaneFailureTolerance: "zone"} - cli := getClientForTests(t) - inputConfig := input.Config{MultiZoneCluster: testCase.multiZone} - step := NewCreateRuntimeResourceStep(memoryStorage.Operations(), memoryStorage.Instances(), cli, kimConfig, inputConfig, nil, false, defaultOIDSConfig) + cli := getClientForTests(t) + step := NewCreateRuntimeResourceStep(memoryStorage.Operations(), memoryStorage.Instances(), cli, kimConfig, inputConfig, nil, false, defaultOIDSConfig) - // when - entry := log.WithFields(logrus.Fields{"step": "TEST"}) - _, repeat, err := step.Run(operation, entry) + // when + entry := log.WithFields(logrus.Fields{"step": "TEST"}) + _, repeat, err := step.Run(operation, entry) - // then - assert.NoError(t, err) - assert.Zero(t, repeat) + // then + assert.NoError(t, err) + assert.Zero(t, repeat) - 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"]) + runtime := imv1.Runtime{} + err = cli.Get(context.Background(), client.ObjectKey{ + Namespace: "kyma-system", + Name: operation.RuntimeID, + }, &runtime) + assert.NoError(t, err) + assert.Equal(t, runtime.Name, operation.RuntimeID) + assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) - assertLabelsKIMDriven(t, operation, runtime) - assertSecurity(t, runtime) + assertLabelsKIMDriven(t, operation, runtime) + assertSecurityNoEgress(t, runtime) - assert.Equal(t, testCase.providerType, runtime.Spec.Shoot.Provider.Type) - assert.Equal(t, testCase.region, runtime.Spec.Shoot.Region) - assert.Equal(t, testCase.purpose, string(runtime.Spec.Shoot.Purpose)) - assertWorkers(t, runtime.Spec.Shoot.Provider.Workers, testCase.machine, testCase.maximum, testCase.minimum, testCase.maxSurge, testCase.maxUnavailable, testCase.zonesCount, testCase.zones) + assert.True(t, *runtime.Spec.Shoot.EnforceSeedLocation) + assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) + assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) + assert.Equal(t, "production", string(runtime.Spec.Shoot.Purpose)) + assert.Equal(t, SecretBindingName, runtime.Spec.Shoot.SecretBindingName) + assertWorkers(t, runtime.Spec.Shoot.Provider.Workers, "m6i.large", 20, 3, 1, 0, 1, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}) + assert.Equal(t, "zone", string(runtime.Spec.Shoot.ControlPlane.HighAvailability.FailureTolerance.Type)) + assertDefaultNetworking(t, runtime.Spec.Shoot.Networking) - _, err = memoryStorage.Instances().GetByID(operation.InstanceID) - assert.NoError(t, err) - }) - } + _, err = memoryStorage.Instances().GetByID(operation.InstanceID) + assert.NoError(t, err) } -func TestCreateRuntimeResourceStep_Defaults_AWS_SingleZone_EnforceSeed_ActualCreation(t *testing.T) { +func TestCreateRuntimeResourceStep_Defaults_AWS_SingleZone_DisableEnterpriseFilter_ActualCreation(t *testing.T) { // given log := logrus.New() memoryStorage := storage.NewMemoryStorage() @@ -256,7 +224,7 @@ func TestCreateRuntimeResourceStep_Defaults_AWS_SingleZone_EnforceSeed_ActualCre err := imv1.AddToScheme(scheme.Scheme) instance, operation := fixInstanceAndOperation(broker.AWSPlanID, "eu-west-2", "platform-region") - operation.ProvisioningParameters.Parameters.ShootAndSeedSameRegion = ptr.Bool(true) + operation.ProvisioningParameters.ErsContext.LicenseType = ptr.String("PARTNER") assertInsertions(t, memoryStorage, instance, operation) kimConfig := fixKimConfig("aws", false) @@ -283,9 +251,9 @@ func TestCreateRuntimeResourceStep_Defaults_AWS_SingleZone_EnforceSeed_ActualCre assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) assertLabelsKIMDriven(t, operation, runtime) - assertSecurity(t, runtime) + assertSecurityWithNetworkingFilter(t, runtime, true) - assert.True(t, *runtime.Spec.Shoot.EnforceSeedLocation) + assert.True(t, runtime.Spec.Security.Networking.Filter.Egress.Enabled) assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) assert.Equal(t, "production", string(runtime.Spec.Shoot.Purpose)) @@ -382,7 +350,7 @@ func TestCreateRuntimeResourceStep_Defaults_AWS_SingleZone_DryRun_ActualCreation assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) assertLabelsProvisionerDriven(t, operation, runtime) - assertSecurity(t, runtime) + assertSecurityNoEgress(t, runtime) assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) @@ -486,7 +454,7 @@ func TestCreateRuntimeResourceStep_Defaults_AWS_MultiZoneWithNetworking_ActualCr assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) assertLabelsKIMDriven(t, operation, runtime) - assertSecurity(t, runtime) + assertSecurityNoEgress(t, runtime) assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) @@ -502,6 +470,97 @@ func TestCreateRuntimeResourceStep_Defaults_AWS_MultiZoneWithNetworking_ActualCr assert.NoError(t, err) } +func TestCreateRuntimeResourceStep_Defaults_AWS_MultiZone_ActualCreation(t *testing.T) { + // given + log := logrus.New() + memoryStorage := storage.NewMemoryStorage() + + err := imv1.AddToScheme(scheme.Scheme) + + instance, operation := fixInstanceAndOperation(broker.AWSPlanID, "eu-west-2", "platform-region") + assertInsertions(t, memoryStorage, instance, operation) + + kimConfig := fixKimConfig("aws", false) + + cli := getClientForTests(t) + inputConfig := input.Config{MultiZoneCluster: true} + step := NewCreateRuntimeResourceStep(memoryStorage.Operations(), memoryStorage.Instances(), cli, kimConfig, inputConfig, nil, false, defaultOIDSConfig) + + // when + entry := log.WithFields(logrus.Fields{"step": "TEST"}) + _, repeat, err := step.Run(operation, entry) + + // then + assert.NoError(t, err) + assert.Zero(t, repeat) + + runtime := imv1.Runtime{} + err = cli.Get(context.Background(), client.ObjectKey{ + Namespace: "kyma-system", + Name: operation.RuntimeID, + }, &runtime) + assert.NoError(t, err) + assert.Equal(t, runtime.Name, operation.RuntimeID) + assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) + + assertLabelsKIMDriven(t, operation, runtime) + assertSecurityNoEgress(t, runtime) + + assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) + assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) + assert.Equal(t, "production", string(runtime.Spec.Shoot.Purpose)) + assertWorkers(t, runtime.Spec.Shoot.Provider.Workers, "m6i.large", 20, 3, 3, 0, 3, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}) + + _, err = memoryStorage.Instances().GetByID(operation.InstanceID) + assert.NoError(t, err) +} + +func TestCreateRuntimeResourceStep_Defaults_Preview_SingleZone_ActualCreation(t *testing.T) { + // given + log := logrus.New() + memoryStorage := storage.NewMemoryStorage() + + err := imv1.AddToScheme(scheme.Scheme) + + instance, operation := fixInstanceAndOperation(broker.PreviewPlanID, "eu-west-2", "platform-region") + assertInsertions(t, memoryStorage, instance, operation) + + kimConfig := fixKimConfig("preview", false) + + cli := getClientForTests(t) + inputConfig := input.Config{MultiZoneCluster: false} + step := NewCreateRuntimeResourceStep(memoryStorage.Operations(), memoryStorage.Instances(), cli, kimConfig, inputConfig, nil, false, defaultOIDSConfig) + + // when + entry := log.WithFields(logrus.Fields{"step": "TEST"}) + _, repeat, err := step.Run(operation, entry) + + // then + assert.NoError(t, err) + assert.Zero(t, repeat) + + 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"]) + + assertLabelsKIMDriven(t, operation, runtime) + assertSecurityNoEgress(t, runtime) + + assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) + assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) + assert.Equal(t, "production", string(runtime.Spec.Shoot.Purpose)) + assertWorkers(t, runtime.Spec.Shoot.Provider.Workers, "m6i.large", 20, 3, 1, 0, 1, []string{"eu-west-2a", "eu-west-2b", "eu-west-2c"}) + + _, err = memoryStorage.Instances().GetByID(operation.InstanceID) + assert.NoError(t, err) + +} + func TestCreateRuntimeResourceStep_Defaults_Preview_SingleZone_ActualCreation_WithRetry(t *testing.T) { // given log := logrus.New() @@ -536,7 +595,7 @@ func TestCreateRuntimeResourceStep_Defaults_Preview_SingleZone_ActualCreation_Wi assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) assertLabelsKIMDriven(t, operation, runtime) - assertSecurity(t, runtime) + assertSecurityNoEgress(t, runtime) assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) @@ -556,7 +615,7 @@ func TestCreateRuntimeResourceStep_Defaults_Preview_SingleZone_ActualCreation_Wi assert.Equal(t, "runtime-58f8c703-1756-48ab-9299-a847974d1fee", runtime.Labels["operator.kyma-project.io/kyma-name"]) assertLabelsKIMDriven(t, operation, runtime) - assertSecurity(t, runtime) + assertSecurityNoEgress(t, runtime) assert.Equal(t, "aws", runtime.Spec.Shoot.Provider.Type) assert.Equal(t, "eu-west-2", runtime.Spec.Shoot.Region) @@ -671,6 +730,30 @@ func TestCreateRuntimeResourceStep_Defaults_Freemium(t *testing.T) { } } +// testing auxiliary functions + +func Test_Defaults(t *testing.T) { + //given + //when + + nilToDefaultString := DefaultIfParamNotSet("default value", nil) + nonDefaultString := DefaultIfParamNotSet("default value", ptr.String("initial value")) + + nilToDefaultInt := DefaultIfParamNotSet(42, nil) + nonDefaultInt := DefaultIfParamNotSet(42, ptr.Integer(7)) + + emptyToDefault := DefaultIfParamZero("default value", "") + nonEmpty := DefaultIfParamZero("default value", "initial value") + + //then + assert.Equal(t, "initial value", nonDefaultString) + assert.Equal(t, "default value", nilToDefaultString) + assert.Equal(t, 42, nilToDefaultInt) + assert.Equal(t, 7, nonDefaultInt) + assert.Equal(t, "default value", emptyToDefault) + assert.Equal(t, "initial value", nonEmpty) +} + // assertions func assertSecurityWithDefaultAdministrator(t *testing.T, runtime imv1.Runtime) { @@ -678,9 +761,13 @@ func assertSecurityWithDefaultAdministrator(t *testing.T, runtime imv1.Runtime) assert.Equal(t, runtime.Spec.Security.Networking.Filter.Egress, imv1.Egress(imv1.Egress{Enabled: false})) } -func assertSecurity(t *testing.T, runtime imv1.Runtime) { +func assertSecurityNoEgress(t *testing.T, runtime imv1.Runtime) { + assertSecurityWithNetworkingFilter(t, runtime, false) +} + +func assertSecurityWithNetworkingFilter(t *testing.T, runtime imv1.Runtime, egress bool) { assert.ElementsMatch(t, runtime.Spec.Security.Administrators, runtimeAdministrators) - assert.Equal(t, runtime.Spec.Security.Networking.Filter.Egress, imv1.Egress(imv1.Egress{Enabled: false})) + assert.Equal(t, runtime.Spec.Security.Networking.Filter.Egress, imv1.Egress(imv1.Egress{Enabled: egress})) } func assertLabelsKIMDriven(t *testing.T, preOperation internal.Operation, runtime imv1.Runtime) {