Skip to content

Commit 7b693ac

Browse files
authored
Add missing fields to datasource (#596)
* add missing fields to datasource * split resource and datasource models
1 parent e11be37 commit 7b693ac

2 files changed

Lines changed: 513 additions & 2 deletions

File tree

stackit/internal/services/iaas/network/datasource.go

Lines changed: 166 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ import (
44
"context"
55
"fmt"
66
"net/http"
7+
"strings"
78

89
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
910
"github.com/hashicorp/terraform-plugin-framework/datasource"
1011
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/diag"
1113
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1214
"github.com/hashicorp/terraform-plugin-framework/types"
1315
"github.com/hashicorp/terraform-plugin-log/tflog"
1416
"github.com/stackitcloud/stackit-sdk-go/core/config"
1517
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
1618
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
1719
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
20+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
1821
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
1922
)
2023

@@ -23,6 +26,28 @@ var (
2326
_ datasource.DataSource = &networkDataSource{}
2427
)
2528

29+
type DataSourceModel struct {
30+
Id types.String `tfsdk:"id"` // needed by TF
31+
ProjectId types.String `tfsdk:"project_id"`
32+
NetworkId types.String `tfsdk:"network_id"`
33+
Name types.String `tfsdk:"name"`
34+
Nameservers types.List `tfsdk:"nameservers"`
35+
IPv4Gateway types.String `tfsdk:"ipv4_gateway"`
36+
IPv4Nameservers types.List `tfsdk:"ipv4_nameservers"`
37+
IPv4Prefix types.String `tfsdk:"ipv4_prefix"`
38+
IPv4PrefixLength types.Int64 `tfsdk:"ipv4_prefix_length"`
39+
Prefixes types.List `tfsdk:"prefixes"`
40+
IPv4Prefixes types.List `tfsdk:"ipv4_prefixes"`
41+
IPv6Gateway types.String `tfsdk:"ipv6_gateway"`
42+
IPv6Nameservers types.List `tfsdk:"ipv6_nameservers"`
43+
IPv6Prefix types.String `tfsdk:"ipv6_prefix"`
44+
IPv6PrefixLength types.Int64 `tfsdk:"ipv6_prefix_length"`
45+
IPv6Prefixes types.List `tfsdk:"ipv6_prefixes"`
46+
PublicIP types.String `tfsdk:"public_ip"`
47+
Labels types.Map `tfsdk:"labels"`
48+
Routed types.Bool `tfsdk:"routed"`
49+
}
50+
2651
// NewNetworkDataSource is a helper function to simplify the provider implementation.
2752
func NewNetworkDataSource() datasource.DataSource {
2853
return &networkDataSource{}
@@ -181,7 +206,7 @@ func (d *networkDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
181206

182207
// Read refreshes the Terraform state with the latest data.
183208
func (d *networkDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
184-
var model Model
209+
var model DataSourceModel
185210
diags := req.Config.Get(ctx, &model)
186211
resp.Diagnostics.Append(diags...)
187212
if resp.Diagnostics.HasError() {
@@ -203,7 +228,7 @@ func (d *networkDataSource) Read(ctx context.Context, req datasource.ReadRequest
203228
return
204229
}
205230

206-
err = mapFields(ctx, networkResp, &model)
231+
err = mapDataSourceFields(ctx, networkResp, &model)
207232
if err != nil {
208233
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading network", fmt.Sprintf("Processing API payload: %v", err))
209234
return
@@ -215,3 +240,142 @@ func (d *networkDataSource) Read(ctx context.Context, req datasource.ReadRequest
215240
}
216241
tflog.Info(ctx, "Network read")
217242
}
243+
244+
func mapDataSourceFields(ctx context.Context, networkResp *iaas.Network, model *DataSourceModel) error {
245+
if networkResp == nil {
246+
return fmt.Errorf("response input is nil")
247+
}
248+
if model == nil {
249+
return fmt.Errorf("model input is nil")
250+
}
251+
252+
var networkId string
253+
if model.NetworkId.ValueString() != "" {
254+
networkId = model.NetworkId.ValueString()
255+
} else if networkResp.NetworkId != nil {
256+
networkId = *networkResp.NetworkId
257+
} else {
258+
return fmt.Errorf("network id not present")
259+
}
260+
261+
idParts := []string{
262+
model.ProjectId.ValueString(),
263+
networkId,
264+
}
265+
model.Id = types.StringValue(
266+
strings.Join(idParts, core.Separator),
267+
)
268+
269+
labels, diags := types.MapValueFrom(ctx, types.StringType, map[string]interface{}{})
270+
if diags.HasError() {
271+
return fmt.Errorf("converting labels to StringValue map: %w", core.DiagsToError(diags))
272+
}
273+
if networkResp.Labels != nil && len(*networkResp.Labels) != 0 {
274+
var diags diag.Diagnostics
275+
labels, diags = types.MapValueFrom(ctx, types.StringType, *networkResp.Labels)
276+
if diags.HasError() {
277+
return fmt.Errorf("converting labels to StringValue map: %w", core.DiagsToError(diags))
278+
}
279+
} else if model.Labels.IsNull() {
280+
labels = types.MapNull(types.StringType)
281+
}
282+
283+
// IPv4
284+
285+
if networkResp.Nameservers == nil {
286+
model.Nameservers = types.ListNull(types.StringType)
287+
model.IPv4Nameservers = types.ListNull(types.StringType)
288+
} else {
289+
respNameservers := *networkResp.Nameservers
290+
modelNameservers, err := utils.ListValuetoStringSlice(model.Nameservers)
291+
modelIPv4Nameservers, errIpv4 := utils.ListValuetoStringSlice(model.IPv4Nameservers)
292+
if err != nil {
293+
return fmt.Errorf("get current network nameservers from model: %w", err)
294+
}
295+
if errIpv4 != nil {
296+
return fmt.Errorf("get current IPv4 network nameservers from model: %w", errIpv4)
297+
}
298+
299+
reconciledNameservers := utils.ReconcileStringSlices(modelNameservers, respNameservers)
300+
reconciledIPv4Nameservers := utils.ReconcileStringSlices(modelIPv4Nameservers, respNameservers)
301+
302+
nameserversTF, diags := types.ListValueFrom(ctx, types.StringType, reconciledNameservers)
303+
ipv4NameserversTF, ipv4Diags := types.ListValueFrom(ctx, types.StringType, reconciledIPv4Nameservers)
304+
if diags.HasError() {
305+
return fmt.Errorf("map network nameservers: %w", core.DiagsToError(diags))
306+
}
307+
if ipv4Diags.HasError() {
308+
return fmt.Errorf("map IPv4 network nameservers: %w", core.DiagsToError(ipv4Diags))
309+
}
310+
311+
model.Nameservers = nameserversTF
312+
model.IPv4Nameservers = ipv4NameserversTF
313+
}
314+
315+
if networkResp.Prefixes == nil {
316+
model.Prefixes = types.ListNull(types.StringType)
317+
model.IPv4Prefixes = types.ListNull(types.StringType)
318+
} else {
319+
respPrefixes := *networkResp.Prefixes
320+
prefixesTF, diags := types.ListValueFrom(ctx, types.StringType, respPrefixes)
321+
if diags.HasError() {
322+
return fmt.Errorf("map network prefixes: %w", core.DiagsToError(diags))
323+
}
324+
325+
model.Prefixes = prefixesTF
326+
model.IPv4Prefixes = prefixesTF
327+
}
328+
329+
if networkResp.Gateway != nil {
330+
model.IPv4Gateway = types.StringPointerValue(networkResp.GetGateway())
331+
} else {
332+
model.IPv4Gateway = types.StringNull()
333+
}
334+
335+
// IPv6
336+
337+
if networkResp.NameserversV6 == nil {
338+
model.IPv6Nameservers = types.ListNull(types.StringType)
339+
} else {
340+
respIPv6Nameservers := *networkResp.NameserversV6
341+
modelIPv6Nameservers, errIpv6 := utils.ListValuetoStringSlice(model.IPv6Nameservers)
342+
if errIpv6 != nil {
343+
return fmt.Errorf("get current IPv6 network nameservers from model: %w", errIpv6)
344+
}
345+
346+
reconciledIPv6Nameservers := utils.ReconcileStringSlices(modelIPv6Nameservers, respIPv6Nameservers)
347+
348+
ipv6NameserversTF, ipv6Diags := types.ListValueFrom(ctx, types.StringType, reconciledIPv6Nameservers)
349+
if ipv6Diags.HasError() {
350+
return fmt.Errorf("map IPv6 network nameservers: %w", core.DiagsToError(ipv6Diags))
351+
}
352+
353+
model.IPv6Nameservers = ipv6NameserversTF
354+
}
355+
356+
if networkResp.PrefixesV6 == nil {
357+
model.IPv6Prefixes = types.ListNull(types.StringType)
358+
} else {
359+
respPrefixesV6 := *networkResp.PrefixesV6
360+
prefixesV6TF, diags := types.ListValueFrom(ctx, types.StringType, respPrefixesV6)
361+
if diags.HasError() {
362+
return fmt.Errorf("map network IPv6 prefixes: %w", core.DiagsToError(diags))
363+
}
364+
365+
model.IPv6Prefixes = prefixesV6TF
366+
}
367+
368+
if networkResp.Gatewayv6 != nil {
369+
model.IPv6Gateway = types.StringPointerValue(networkResp.GetGatewayv6())
370+
} else {
371+
model.IPv6Gateway = types.StringNull()
372+
}
373+
374+
model.NetworkId = types.StringValue(networkId)
375+
model.Name = types.StringPointerValue(networkResp.Name)
376+
model.PublicIP = types.StringPointerValue(networkResp.PublicIp)
377+
model.Labels = labels
378+
model.Routed = types.BoolPointerValue(networkResp.Routed)
379+
380+
return nil
381+
}

0 commit comments

Comments
 (0)