Skip to content

Commit d9dc1d4

Browse files
authored
feat(iaas): add iaas network v2 alpha (#899)
* add experimental network v2
1 parent a00b046 commit d9dc1d4

28 files changed

+3766
-912
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ To enable experiments set the experiments field in the provider definition:
183183
```hcl
184184
provider "stackit" {
185185
default_region = "eu01"
186-
experiments = ["iam", "routing-tables"]
186+
experiments = ["iam", "routing-tables", "network"]
187187
}
188188
```
189189

@@ -197,6 +197,12 @@ Enables IAM management features in the Terraform provider. The underlying IAM AP
197197

198198
This feature enables experimental routing table capabilities in the Terraform Provider, available only to designated SNAs at this time.
199199

200+
#### `network`
201+
202+
The `stackit_network` provides the fields `region` and `routing_table_id` when the experiment flag `network` is set.
203+
The underlying API is not stable yet and could change in the future.
204+
If you don't need these fields, don't set the experiment flag `network`, to use the stable api.
205+
200206
## Acceptance Tests
201207

202208
Terraform acceptance tests are run using the command `make test-acceptance-tf`. For all services,

docs/data-sources/network.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ data "stackit_network" "example" {
2727
- `network_id` (String) The network ID.
2828
- `project_id` (String) STACKIT project ID to which the network is associated.
2929

30+
### Optional
31+
32+
- `region` (String) Can only be used when experimental "network" is set. This is likely going to undergo significant changes or be removed in the future.
33+
The resource region. If not defined, the provider region is used.
34+
3035
### Read-Only
3136

3237
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`network_id`".
@@ -46,3 +51,5 @@ data "stackit_network" "example" {
4651
- `prefixes` (List of String, Deprecated) The prefixes of the network. This field is deprecated and will be removed soon, use `ipv4_prefixes` to read the prefixes of the IPv4 networks.
4752
- `public_ip` (String) The public IP of the network.
4853
- `routed` (Boolean) Shows if the network is routed and therefore accessible from other networks.
54+
- `routing_table_id` (String) Can only be used when experimental "network" is set. This is likely going to undergo significant changes or be removed in the future. Use it at your own discretion.
55+
The ID of the routing table associated with the network.

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Note: AWS specific checks must be skipped as they do not work on STACKIT. For de
157157
- `default_region` (String) Region will be used as the default location for regional services. Not all services require a region, some are global
158158
- `dns_custom_endpoint` (String) Custom endpoint for the DNS service
159159
- `enable_beta_resources` (Boolean) Enable beta resources. Default is false.
160-
- `experiments` (List of String) Enables experiments. These are unstable features without official support. More information can be found in the README. Available Experiments: [iam routing-tables]
160+
- `experiments` (List of String) Enables experiments. These are unstable features without official support. More information can be found in the README. Available Experiments: iam, routing-tables, network
161161
- `git_custom_endpoint` (String) Custom endpoint for the Git service
162162
- `iaas_custom_endpoint` (String) Custom endpoint for the IaaS service
163163
- `loadbalancer_custom_endpoint` (String) Custom endpoint for the Load Balancer service

docs/resources/network.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ resource "stackit_network" "example_non_routed_network" {
6363
- `nameservers` (List of String, Deprecated) The nameservers of the network. This field is deprecated and will be removed soon, use `ipv4_nameservers` to configure the nameservers for IPv4.
6464
- `no_ipv4_gateway` (Boolean) If set to `true`, the network doesn't have a gateway.
6565
- `no_ipv6_gateway` (Boolean) If set to `true`, the network doesn't have a gateway.
66+
- `region` (String) Can only be used when experimental "network" is set.
67+
The resource region. If not defined, the provider region is used.
6668
- `routed` (Boolean) If set to `true`, the network is routed and therefore accessible from other networks.
69+
- `routing_table_id` (String) Can only be used when experimental "network" is set.
70+
The ID of the routing table associated with the network.
6771

6872
### Read-Only
6973

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/stackitcloud/stackit-sdk-go/services/dns v0.17.0
1717
github.com/stackitcloud/stackit-sdk-go/services/git v0.6.0
1818
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.26.0
19-
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.19-alpha
19+
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha
2020
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.4.0
2121
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.0
2222
github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ github.com/stackitcloud/stackit-sdk-go/services/git v0.6.0 h1:C+8z3MdvnTngcH9L72
162162
github.com/stackitcloud/stackit-sdk-go/services/git v0.6.0/go.mod h1:agI7SONeLR/IZL3TOgn1tDzfS63O2rWKQE8+huRjEzU=
163163
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.26.0 h1:7qm/Tft79wFlHomPdgjUJ9uJU8kEk+k9ficMGRoHtf0=
164164
github.com/stackitcloud/stackit-sdk-go/services/iaas v0.26.0/go.mod h1:lUGkcbyMkd4nRBDFmKohIwlgtOZqQo4Ek5S5ajw90Xg=
165-
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.19-alpha h1:HnQyJSXbtYzN9IhTO02zxLrcSxyauIbeJD+GTf23A50=
166-
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.19-alpha/go.mod h1:Wt77ucOwpe9g/84LijU+YhWbn3vLcpkAoRy2i+FobNQ=
165+
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha h1:m1jq6a8dbUe+suFuUNdHmM/cSehpGLUtDbK1CqLqydg=
166+
github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.21-alpha/go.mod h1:Nu1b5Phsv8plgZ51+fkxPVsU91ZJ5Ayz+cthilxdmQ8=
167167
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.4.0 h1:Ef4SyTBjIkfwaws4mssa6AoK+OokHFtr7ZIflUpoXVE=
168168
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.4.0/go.mod h1:FiVhDlw9+yuTiUmnyGLn2qpsLW26w9OC4TS1y78czvg=
169169
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.0 h1:QKOfaB7EcuJmBCxpFXN2K7g2ih0gQM6cyZ1VhTmtQfI=

stackit/internal/features/experiments.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import (
1313

1414
const (
1515
RoutingTablesExperiment = "routing-tables"
16+
NetworkExperiment = "network"
17+
IamExperiment = "iam"
1618
)
1719

18-
var AvailableExperiments = []string{"iam", RoutingTablesExperiment}
20+
var AvailableExperiments = []string{IamExperiment, RoutingTablesExperiment, NetworkExperiment}
1921

2022
// Check if an experiment is valid.
2123
func ValidExperiment(experiment string, diags *diag.Diagnostics) bool {
@@ -31,11 +33,21 @@ func ValidExperiment(experiment string, diags *diag.Diagnostics) bool {
3133

3234
// Check if an experiment is enabled.
3335
func CheckExperimentEnabled(ctx context.Context, data *core.ProviderData, experiment, resourceName string, resourceType core.ResourceType, diags *diag.Diagnostics) {
36+
if CheckExperimentEnabledWithoutError(ctx, data, experiment, resourceName, resourceType, diags) {
37+
return
38+
}
39+
errTitle := fmt.Sprintf("%s is part of the %s experiment, which is currently disabled by default", resourceName, experiment)
40+
errContent := fmt.Sprintf(`Enable the %s experiment by adding it into your provider block.`, experiment)
41+
tflog.Error(ctx, fmt.Sprintf("%s | %s", errTitle, errContent))
42+
diags.AddError(errTitle, errContent)
43+
}
44+
45+
func CheckExperimentEnabledWithoutError(ctx context.Context, data *core.ProviderData, experiment, resourceName string, resourceType core.ResourceType, diags *diag.Diagnostics) bool {
3446
if !ValidExperiment(experiment, diags) {
3547
errTitle := fmt.Sprintf("The experiment %s does not exist.", experiment)
3648
errContent := "This is a bug in the STACKIT Terraform Provider. Please open an issue here: https://github.com/stackitcloud/terraform-provider-stackit/issues"
3749
diags.AddError(errTitle, errContent)
38-
return
50+
return false
3951
}
4052
experimentActive := slices.ContainsFunc(data.Experiments, func(e string) bool {
4153
return strings.EqualFold(e, experiment)
@@ -46,12 +58,9 @@ func CheckExperimentEnabled(ctx context.Context, data *core.ProviderData, experi
4658
warnContent := fmt.Sprintf("This %s is part of the %s experiment and is likely going to undergo significant changes or be removed in the future. Use it at your own discretion.", resourceType, experiment)
4759
tflog.Warn(ctx, fmt.Sprintf("%s | %s", warnTitle, warnContent))
4860
diags.AddWarning(warnTitle, warnContent)
49-
return
61+
return true
5062
}
51-
errTitle := fmt.Sprintf("%s is part of the %s experiment, which is currently disabled by default", resourceName, experiment)
52-
errContent := fmt.Sprintf(`Enable the %s experiment by adding it into your provider block.`, experiment)
53-
tflog.Error(ctx, fmt.Sprintf("%s | %s", errTitle, errContent))
54-
diags.AddError(errTitle, errContent)
63+
return false
5564
}
5665

5766
func AddExperimentDescription(description, experiment string, resourceType core.ResourceType) string {

stackit/internal/features/experiments_test.go

Lines changed: 141 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func TestValidExperiment(t *testing.T) {
2121
{
2222
name: "valid",
2323
args: args{
24-
experiment: "iam",
24+
experiment: IamExperiment,
2525
diags: &diag.Diagnostics{},
2626
},
2727
want: true,
@@ -64,9 +64,9 @@ func TestCheckExperimentEnabled(t *testing.T) {
6464
args: args{
6565
ctx: context.Background(),
6666
data: &core.ProviderData{
67-
Experiments: []string{"iam"},
67+
Experiments: []string{IamExperiment},
6868
},
69-
experiment: "iam",
69+
experiment: IamExperiment,
7070
resourceType: core.Resource,
7171
diags: &diag.Diagnostics{},
7272
},
@@ -80,7 +80,7 @@ func TestCheckExperimentEnabled(t *testing.T) {
8080
data: &core.ProviderData{
8181
Experiments: []string{},
8282
},
83-
experiment: "iam",
83+
experiment: IamExperiment,
8484
resourceType: core.Resource,
8585
diags: &diag.Diagnostics{},
8686
},
@@ -92,7 +92,7 @@ func TestCheckExperimentEnabled(t *testing.T) {
9292
args: args{
9393
ctx: context.Background(),
9494
data: &core.ProviderData{
95-
Experiments: []string{"iam"},
95+
Experiments: []string{IamExperiment},
9696
},
9797
experiment: "foobar",
9898
resourceType: core.Resource,
@@ -101,6 +101,34 @@ func TestCheckExperimentEnabled(t *testing.T) {
101101
wantDiagsErr: true,
102102
wantDiagsWarning: false,
103103
},
104+
{
105+
name: "enabled multiple experiment",
106+
args: args{
107+
ctx: context.Background(),
108+
data: &core.ProviderData{
109+
Experiments: []string{IamExperiment, NetworkExperiment, RoutingTablesExperiment},
110+
},
111+
experiment: NetworkExperiment,
112+
resourceType: core.Resource,
113+
diags: &diag.Diagnostics{},
114+
},
115+
wantDiagsErr: false,
116+
wantDiagsWarning: true,
117+
},
118+
{
119+
name: "enabled multiple experiment - without the required experiment",
120+
args: args{
121+
ctx: context.Background(),
122+
data: &core.ProviderData{
123+
Experiments: []string{IamExperiment, RoutingTablesExperiment},
124+
},
125+
experiment: NetworkExperiment,
126+
resourceType: core.Resource,
127+
diags: &diag.Diagnostics{},
128+
},
129+
wantDiagsErr: true,
130+
wantDiagsWarning: false,
131+
},
104132
}
105133
for _, tt := range tests {
106134
t.Run(tt.name, func(t *testing.T) {
@@ -114,3 +142,111 @@ func TestCheckExperimentEnabled(t *testing.T) {
114142
})
115143
}
116144
}
145+
146+
func TestCheckExperimentEnabledWithoutError(t *testing.T) {
147+
type args struct {
148+
ctx context.Context
149+
data *core.ProviderData
150+
experiment string
151+
resourceName string
152+
resourceType core.ResourceType
153+
diags *diag.Diagnostics
154+
}
155+
tests := []struct {
156+
name string
157+
args args
158+
wantEnabled bool
159+
wantDiagsErr bool
160+
wantDiagsWarning bool
161+
}{
162+
163+
{
164+
name: "enabled",
165+
args: args{
166+
ctx: context.Background(),
167+
data: &core.ProviderData{
168+
Experiments: []string{IamExperiment},
169+
},
170+
experiment: IamExperiment,
171+
resourceType: core.Resource,
172+
diags: &diag.Diagnostics{},
173+
},
174+
wantEnabled: true,
175+
wantDiagsErr: false,
176+
wantDiagsWarning: true,
177+
},
178+
{
179+
name: "disabled - no error",
180+
args: args{
181+
ctx: context.Background(),
182+
data: &core.ProviderData{
183+
Experiments: []string{},
184+
},
185+
experiment: NetworkExperiment,
186+
resourceType: core.Resource,
187+
diags: &diag.Diagnostics{},
188+
},
189+
wantEnabled: false,
190+
wantDiagsErr: false,
191+
wantDiagsWarning: false,
192+
},
193+
{
194+
name: "invalid experiment",
195+
args: args{
196+
ctx: context.Background(),
197+
data: &core.ProviderData{
198+
Experiments: []string{IamExperiment},
199+
},
200+
experiment: "foobar",
201+
resourceType: core.Resource,
202+
diags: &diag.Diagnostics{},
203+
},
204+
wantEnabled: false,
205+
wantDiagsErr: true,
206+
wantDiagsWarning: false,
207+
},
208+
{
209+
name: "enabled multiple experiment",
210+
args: args{
211+
ctx: context.Background(),
212+
data: &core.ProviderData{
213+
Experiments: []string{IamExperiment, NetworkExperiment, RoutingTablesExperiment},
214+
},
215+
experiment: NetworkExperiment,
216+
resourceType: core.Resource,
217+
diags: &diag.Diagnostics{},
218+
},
219+
wantEnabled: true,
220+
wantDiagsErr: false,
221+
wantDiagsWarning: true,
222+
},
223+
{
224+
name: "enabled multiple experiment - without the required experiment",
225+
args: args{
226+
ctx: context.Background(),
227+
data: &core.ProviderData{
228+
Experiments: []string{IamExperiment, RoutingTablesExperiment},
229+
},
230+
experiment: NetworkExperiment,
231+
resourceType: core.Resource,
232+
diags: &diag.Diagnostics{},
233+
},
234+
wantEnabled: false,
235+
wantDiagsErr: false,
236+
wantDiagsWarning: false,
237+
},
238+
}
239+
for _, tt := range tests {
240+
t.Run(tt.name, func(t *testing.T) {
241+
if got := CheckExperimentEnabledWithoutError(tt.args.ctx, tt.args.data, tt.args.experiment, tt.args.resourceName, tt.args.resourceType, tt.args.diags); got != tt.wantEnabled {
242+
t.Errorf("CheckExperimentEnabledWithoutError() = %v, want %v", got, tt.wantEnabled)
243+
}
244+
if got := tt.args.diags.HasError(); got != tt.wantDiagsErr {
245+
t.Errorf("CheckExperimentEnabled() diags.HasError() = %v, want %v", got, tt.wantDiagsErr)
246+
}
247+
if got := tt.args.diags.WarningsCount() > 0; got != tt.wantDiagsWarning {
248+
t.Errorf("CheckExperimentEnabled() diags.WarningsCount() > 0 = %v, want %v", got, tt.wantDiagsErr)
249+
}
250+
})
251+
}
252+
}

stackit/internal/services/authorization/roleassignments/resource.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ var roleTargets = []string{
3232
"organization",
3333
}
3434

35-
// This resource is part of the "iam" experiment
36-
var experiment = "iam"
37-
3835
// Ensure the implementation satisfies the expected interfaces.
3936
var (
4037
_ resource.Resource = &roleAssignmentResource{}
@@ -84,7 +81,7 @@ func (r *roleAssignmentResource) Configure(ctx context.Context, req resource.Con
8481
return
8582
}
8683

87-
features.CheckExperimentEnabled(ctx, &providerData, experiment, fmt.Sprintf("stackit_authorization_%s_role_assignment", r.apiName), core.Resource, &resp.Diagnostics)
84+
features.CheckExperimentEnabled(ctx, &providerData, features.IamExperiment, fmt.Sprintf("stackit_authorization_%s_role_assignment", r.apiName), core.Resource, &resp.Diagnostics)
8885
if resp.Diagnostics.HasError() {
8986
return
9087
}
@@ -100,7 +97,7 @@ func (r *roleAssignmentResource) Configure(ctx context.Context, req resource.Con
10097
// Schema defines the schema for the resource.
10198
func (r *roleAssignmentResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
10299
descriptions := map[string]string{
103-
"main": features.AddExperimentDescription(fmt.Sprintf("%s Role Assignment resource schema.", r.apiName), experiment, core.Resource),
100+
"main": features.AddExperimentDescription(fmt.Sprintf("%s Role Assignment resource schema.", r.apiName), features.IamExperiment, core.Resource),
104101
"id": "Terraform's internal resource identifier. It is structured as \"[resource_id],[role],[subject]\".",
105102
"resource_id": fmt.Sprintf("%s Resource to assign the role to.", r.apiName),
106103
"role": "Role to be assigned",

0 commit comments

Comments
 (0)