diff --git a/docs/data-sources/loadbalancer.md b/docs/data-sources/loadbalancer.md index 3c967774f..904e9ccf8 100644 --- a/docs/data-sources/loadbalancer.md +++ b/docs/data-sources/loadbalancer.md @@ -135,25 +135,14 @@ Read-Only: ### Nested Schema for `target_pools` -Optional: - -- `session_persistence` (Attributes) Here you can setup various session persistence options, so far only "`use_source_ip_address`" is supported. (see [below for nested schema](#nestedatt--target_pools--session_persistence)) - Read-Only: - `active_health_check` (Attributes) (see [below for nested schema](#nestedatt--target_pools--active_health_check)) - `name` (String) Target pool name. +- `session_persistence` (Attributes) Here you can setup various session persistence options, so far only "`use_source_ip_address`" is supported. (see [below for nested schema](#nestedatt--target_pools--session_persistence)) - `target_port` (Number) Identical port number where each target listens for traffic. - `targets` (Attributes List) List of all targets which will be used in the pool. Limited to 1000. (see [below for nested schema](#nestedatt--target_pools--targets)) - -### Nested Schema for `target_pools.session_persistence` - -Optional: - -- `use_source_ip_address` (Boolean) If true then all connections from one source IP address are redirected to the same target. This setting changes the load balancing algorithm to Maglev. - - ### Nested Schema for `target_pools.active_health_check` @@ -166,6 +155,14 @@ Read-Only: - `unhealthy_threshold` (Number) Unhealthy threshold of the health checking. + +### Nested Schema for `target_pools.session_persistence` + +Read-Only: + +- `use_source_ip_address` (Boolean) If true then all connections from one source IP address are redirected to the same target. This setting changes the load balancing algorithm to Maglev. + + ### Nested Schema for `target_pools.targets` diff --git a/stackit/internal/services/loadbalancer/loadbalancer/datasource.go b/stackit/internal/services/loadbalancer/loadbalancer/datasource.go index e6d9260c8..798867c79 100644 --- a/stackit/internal/services/loadbalancer/loadbalancer/datasource.go +++ b/stackit/internal/services/loadbalancer/loadbalancer/datasource.go @@ -335,13 +335,11 @@ func (r *loadBalancerDataSource) Schema(_ context.Context, _ datasource.SchemaRe }, "session_persistence": schema.SingleNestedAttribute{ Description: descriptions["session_persistence"], - Optional: true, - Computed: false, + Computed: true, Attributes: map[string]schema.Attribute{ "use_source_ip_address": schema.BoolAttribute{ Description: descriptions["use_source_ip_address"], - Optional: true, - Computed: false, + Computed: true, }, }, }, diff --git a/stackit/internal/services/loadbalancer/loadbalancer/resource.go b/stackit/internal/services/loadbalancer/loadbalancer/resource.go index e5d2ddd04..b87171a91 100644 --- a/stackit/internal/services/loadbalancer/loadbalancer/resource.go +++ b/stackit/internal/services/loadbalancer/loadbalancer/resource.go @@ -683,12 +683,13 @@ The example below creates the supporting infrastructure using the STACKIT Terraf "session_persistence": schema.SingleNestedAttribute{ Description: descriptions["session_persistence"], Optional: true, - Computed: false, + Computed: true, Attributes: map[string]schema.Attribute{ "use_source_ip_address": schema.BoolAttribute{ Description: descriptions["use_source_ip_address"], Optional: true, - Computed: false, + Computed: true, + Default: booldefault.StaticBool(false), }, }, }, @@ -1751,13 +1752,13 @@ func mapTargets(targetsResp []loadbalancer.Target, tp map[string]attr.Value) err } func mapSessionPersistence(sessionPersistenceResp *loadbalancer.SessionPersistence, tp map[string]attr.Value) error { - if sessionPersistenceResp == nil { - tp["session_persistence"] = types.ObjectNull(sessionPersistenceTypes) - return nil + useSourceIpAddress := false + if sessionPersistenceResp != nil && sessionPersistenceResp.UseSourceIpAddress != nil { + useSourceIpAddress = *sessionPersistenceResp.UseSourceIpAddress } sessionPersistenceMap := map[string]attr.Value{ - "use_source_ip_address": types.BoolPointerValue(sessionPersistenceResp.UseSourceIpAddress), + "use_source_ip_address": types.BoolValue(useSourceIpAddress), } sessionPersistenceTF, diags := types.ObjectValue(sessionPersistenceTypes, sessionPersistenceMap) diff --git a/stackit/internal/services/loadbalancer/loadbalancer/resource_test.go b/stackit/internal/services/loadbalancer/loadbalancer/resource_test.go index c5ba0e2e5..a08c6901c 100644 --- a/stackit/internal/services/loadbalancer/loadbalancer/resource_test.go +++ b/stackit/internal/services/loadbalancer/loadbalancer/resource_test.go @@ -1240,3 +1240,68 @@ func Test_toUpdatePayload(t *testing.T) { }) } } + +func Test_mapSessionPersistence(t *testing.T) { + tests := []struct { + name string + sessionPersistenceResp *loadbalancer.SessionPersistence + wantTp map[string]attr.Value + wantErr bool + }{ + { + name: "session persistence is nil", + sessionPersistenceResp: nil, + wantTp: map[string]attr.Value{ + "session_persistence": types.ObjectValueMust(sessionPersistenceTypes, + map[string]attr.Value{ + "use_source_ip_address": types.BoolValue(false), + }, + ), + }, + }, + { + name: "use source ip address is false", + sessionPersistenceResp: &loadbalancer.SessionPersistence{ + UseSourceIpAddress: new(false), + }, + wantTp: map[string]attr.Value{ + "session_persistence": types.ObjectValueMust(sessionPersistenceTypes, + map[string]attr.Value{ + "use_source_ip_address": types.BoolValue(false), + }, + ), + }, + }, + { + name: "use source ip address is true", + sessionPersistenceResp: &loadbalancer.SessionPersistence{ + UseSourceIpAddress: new(true), + }, + wantTp: map[string]attr.Value{ + "session_persistence": types.ObjectValueMust(sessionPersistenceTypes, + map[string]attr.Value{ + "use_source_ip_address": types.BoolValue(true), + }, + ), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resultTp := map[string]attr.Value{} + gotErr := mapSessionPersistence(tt.sessionPersistenceResp, resultTp) + if gotErr != nil { + if !tt.wantErr { + t.Errorf("mapSessionPersistence() failed: %v", gotErr) + } + return + } + if tt.wantErr { + t.Fatal("mapSessionPersistence() succeeded unexpectedly") + } + if diff := cmp.Diff(tt.wantTp, resultTp); diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/stackit/internal/services/loadbalancer/loadbalancer_acc_test.go b/stackit/internal/services/loadbalancer/loadbalancer_acc_test.go index 6809a0fc7..85f857805 100644 --- a/stackit/internal/services/loadbalancer/loadbalancer_acc_test.go +++ b/stackit/internal/services/loadbalancer/loadbalancer_acc_test.go @@ -527,7 +527,8 @@ func TestAccLoadBalancerResourceMax(t *testing.T) { resource.TestCheckResourceAttr("stackit_loadbalancer.loadbalancer", "target_pools.1.targets.0.display_name", testutil.ConvertConfigVariable(configVarsMaxUpdated()["target_display_name"])), resource.TestCheckResourceAttrSet("stackit_loadbalancer.loadbalancer", "target_pools.1.targets.0.ip"), - resource.TestCheckNoResourceAttr("stackit_loadbalancer.loadbalancer", "target_pools.0.session_persistence"), + resource.TestCheckResourceAttr("stackit_loadbalancer.loadbalancer", "target_pools.0.session_persistence.%", "1"), + resource.TestCheckResourceAttr("stackit_loadbalancer.loadbalancer", "target_pools.0.session_persistence.use_source_ip_address", testutil.ConvertConfigVariable(configVarsMaxUpdated()["sni_use_source_ip_address"])), resource.TestCheckResourceAttr("stackit_loadbalancer.loadbalancer", "options.private_network_only", testutil.ConvertConfigVariable(configVarsMaxUpdated()["private_network_only"])), resource.TestCheckResourceAttr("stackit_loadbalancer.loadbalancer", "options.acl.0", testutil.ConvertConfigVariable(configVarsMaxUpdated()["acl"])), diff --git a/stackit/internal/services/loadbalancer/testfiles/resource-max.tf b/stackit/internal/services/loadbalancer/testfiles/resource-max.tf index 59503afe9..4ab8935cf 100644 --- a/stackit/internal/services/loadbalancer/testfiles/resource-max.tf +++ b/stackit/internal/services/loadbalancer/testfiles/resource-max.tf @@ -109,9 +109,9 @@ resource "stackit_loadbalancer" "loadbalancer" { timeout = var.sni_health_timeout unhealthy_threshold = var.sni_unhealthy_threshold } - session_persistence = var.sni_use_source_ip_address ? { + session_persistence = { use_source_ip_address = var.sni_use_source_ip_address - } : null + } }, { name = var.udp_target_pool_name