feat(iaas): add warning that behavior of network resource will change (#1031)

relates to STACKITTPR-366

* feat(iaas): add warning that behavior of network resource will change
* fix: changed payload for ipv6_nameservers
  * if is unset / null: ipv6_nameservers will not be sent
  * if set list / empty list: ipv6_nameserver will be sent with the set list / empty list
This commit is contained in:
Marcel Jacek 2025-11-03 13:04:15 +01:00 committed by GitHub
parent 10eced46c7
commit 4552b14edd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 372 additions and 47 deletions

View file

@ -2,9 +2,11 @@ package network
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@ -37,6 +39,13 @@ var (
_ resource.ResourceWithImportState = &networkResource{}
)
const (
ipv4BehaviorChangeTitle = "Behavior of not configured `ipv4_nameservers` will change from January 2026"
ipv4BehaviorChangeDescription = "When `ipv4_nameservers` is not set, it will be set to the network area's `default_nameservers`.\n" +
"To prevent any nameserver configuration, the `ipv4_nameservers` attribute should be explicitly set to an empty list `[]`.\n" +
"In cases where `ipv4_nameservers` are defined within the resource, the existing behavior will remain unchanged."
)
// NewNetworkResource is a helper function to simplify the provider implementation.
func NewNetworkResource() resource.Resource {
return &networkResource{}
@ -88,10 +97,6 @@ func (r *networkResource) Configure(ctx context.Context, req resource.ConfigureR
// ModifyPlan implements resource.ResourceWithModifyPlan.
// Use the modifier to set the effective region in the current plan.
func (r *networkResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { // nolint:gocritic // function signature required by Terraform
// If the v1 api is used, it's not required to get the fallback region because it isn't used
if !r.isExperimental {
return
}
var configModel model.Model
// skip initial empty configuration to avoid follow-up errors
if req.Config.Raw.IsNull() {
@ -108,6 +113,15 @@ func (r *networkResource) ModifyPlan(ctx context.Context, req resource.ModifyPla
return
}
// Warning should only be shown during the plan of the creation. This can be detected by checking if the ID is set.
if utils.IsUndefined(planModel.Id) && utils.IsUndefined(planModel.IPv4Nameservers) {
addIPv4Warning(&resp.Diagnostics)
}
// If the v1 api is used, it's not required to get the fallback region because it isn't used
if !r.isExperimental {
return
}
utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
if resp.Diagnostics.HasError() {
return
@ -171,8 +185,11 @@ func (r *networkResource) ConfigValidators(_ context.Context) []resource.ConfigV
// Schema defines the schema for the resource.
func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
description := "Network resource schema. Must have a `region` specified in the provider configuration."
descriptionNote := fmt.Sprintf("~> %s. %s", ipv4BehaviorChangeTitle, ipv4BehaviorChangeDescription)
resp.Schema = schema.Schema{
Description: "Network resource schema. Must have a `region` specified in the provider configuration.",
MarkdownDescription: fmt.Sprintf("%s\n%s", description, descriptionNote),
Description: description,
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "Terraform's internal resource ID. It is structured as \"`project_id`,`network_id`\".",
@ -212,7 +229,7 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
},
},
"nameservers": schema.ListAttribute{
Description: "The nameservers of the network. This field is deprecated and will be removed soon, use `ipv4_nameservers` to configure the nameservers for IPv4.",
Description: "The nameservers of the network. This field is deprecated and will be removed in January 2026, use `ipv4_nameservers` to configure the nameservers for IPv4.",
DeprecationMessage: "Use `ipv4_nameservers` to configure the nameservers for IPv4.",
Optional: true,
Computed: true,
@ -259,7 +276,7 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
},
},
"prefixes": schema.ListAttribute{
Description: "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.",
Description: "The prefixes of the network. This field is deprecated and will be removed in January 2026, use `ipv4_prefixes` to read the prefixes of the IPv4 networks.",
DeprecationMessage: "Use `ipv4_prefixes` to read the prefixes of the IPv4 networks.",
Computed: true,
ElementType: types.StringType,
@ -299,6 +316,7 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
"ipv6_prefix": schema.StringAttribute{
Description: "The IPv6 prefix of the network (CIDR).",
Optional: true,
Computed: true,
Validators: []validator.String{
validate.CIDR(),
},
@ -309,6 +327,7 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
"ipv6_prefix_length": schema.Int64Attribute{
Description: "The IPv6 prefix length of the network.",
Optional: true,
Computed: true,
},
"ipv6_prefixes": schema.ListAttribute{
Description: "The IPv6 prefixes of the network.",
@ -366,6 +385,18 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
// Create creates the resource and sets the initial Terraform state.
func (r *networkResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { // nolint:gocritic // function signature required by Terraform
// Retrieve values from plan
var planModel model.Model
diags := req.Plan.Get(ctx, &planModel)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// When IPv4Nameserver is not set, print warning that the behavior of ipv4_nameservers will change
if utils.IsUndefined(planModel.IPv4Nameservers) {
addIPv4Warning(&resp.Diagnostics)
}
if !r.isExperimental {
v1network.Create(ctx, req, resp, r.client)
} else {
@ -409,3 +440,9 @@ func (r *networkResource) ImportState(ctx context.Context, req resource.ImportSt
v2network.ImportState(ctx, req, resp)
}
}
func addIPv4Warning(diags *diag.Diagnostics) {
diags.AddAttributeWarning(path.Root("ipv4_nameservers"),
ipv4BehaviorChangeTitle,
ipv4BehaviorChangeDescription)
}

View file

@ -322,8 +322,10 @@ func mapFields(ctx context.Context, networkResp *iaas.Network, model *networkMod
model.IPv6Nameservers = ipv6NameserversTF
}
if networkResp.PrefixesV6 == nil {
if networkResp.PrefixesV6 == nil || len(*networkResp.PrefixesV6) == 0 {
model.IPv6Prefixes = types.ListNull(types.StringType)
model.IPv6Prefix = types.StringNull()
model.IPv6PrefixLength = types.Int64Null()
} else {
respPrefixesV6 := *networkResp.PrefixesV6
prefixesV6TF, diags := types.ListValueFrom(ctx, types.StringType, respPrefixesV6)
@ -367,21 +369,32 @@ func toCreatePayload(ctx context.Context, model *networkModel.Model) (*iaas.Crea
}
addressFamily := &iaas.CreateNetworkAddressFamily{}
modelIPv6Nameservers := []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
var modelIPv6Nameservers []string
// Is true when IPv6Nameservers is not null or unset
if !utils.IsUndefined(model.IPv6Nameservers) {
// If ipv6Nameservers is empty, modelIPv6Nameservers will be set to an empty slice.
// empty slice != nil slice. Empty slice will result in an empty list in the payload []. Nil slice will result in a payload without the property set
modelIPv6Nameservers = []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
if !(model.IPv6Prefix.IsNull() || model.IPv6PrefixLength.IsNull() || model.IPv6Nameservers.IsNull()) {
if !utils.IsUndefined(model.IPv6Prefix) || !utils.IsUndefined(model.IPv6PrefixLength) || (modelIPv6Nameservers != nil) {
addressFamily.Ipv6 = &iaas.CreateNetworkIPv6Body{
Nameservers: &modelIPv6Nameservers,
Prefix: conversion.StringValueToPointer(model.IPv6Prefix),
PrefixLength: conversion.Int64ValueToPointer(model.IPv6PrefixLength),
}
// IPv6 nameservers should only be set, if it contains any value. If the slice is nil, it should NOT be set.
// Setting it to a nil slice would result in a payload, where nameservers is set to null in the json payload,
// but it should actually be unset. Setting it to "null" will result in an error, because it's NOT nullable.
if modelIPv6Nameservers != nil {
addressFamily.Ipv6.Nameservers = &modelIPv6Nameservers
}
if model.NoIPv6Gateway.ValueBool() {
addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil)
@ -445,23 +458,34 @@ func toUpdatePayload(ctx context.Context, model, stateModel *networkModel.Model)
}
addressFamily := &iaas.UpdateNetworkAddressFamily{}
modelIPv6Nameservers := []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
var modelIPv6Nameservers []string
// Is true when IPv6Nameservers is not null or unset
if !utils.IsUndefined(model.IPv6Nameservers) {
// If ipv6Nameservers is empty, modelIPv6Nameservers will be set to an empty slice.
// empty slice != nil slice. Empty slice will result in an empty list in the payload []. Nil slice will result in a payload without the property set
modelIPv6Nameservers = []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
if !(model.IPv6Nameservers.IsNull() || model.IPv6Nameservers.IsUnknown()) {
addressFamily.Ipv6 = &iaas.UpdateNetworkIPv6Body{
Nameservers: &modelIPv6Nameservers,
if !utils.IsUndefined(model.NoIPv6Gateway) || !utils.IsUndefined(model.IPv6Gateway) || modelIPv6Nameservers != nil {
addressFamily.Ipv6 = &iaas.UpdateNetworkIPv6Body{}
// IPv6 nameservers should only be set, if it contains any value. If the slice is nil, it should NOT be set.
// Setting it to a nil slice would result in a payload, where nameservers is set to null in the json payload,
// but it should actually be unset. Setting it to "null" will result in an error, because it's NOT nullable.
if modelIPv6Nameservers != nil {
addressFamily.Ipv6.Nameservers = &modelIPv6Nameservers
}
if model.NoIPv6Gateway.ValueBool() {
addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil)
} else if !(model.IPv6Gateway.IsUnknown() || model.IPv6Gateway.IsNull()) {
} else if !utils.IsUndefined(model.IPv6Gateway) {
addressFamily.Ipv6.Gateway = iaas.NewNullableString(conversion.StringValueToPointer(model.IPv6Gateway))
}
}

View file

@ -466,6 +466,66 @@ func TestToCreatePayload(t *testing.T) {
},
true,
},
{
"ipv6_nameserver_null",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListNull(types.StringType),
IPv6PrefixLength: types.Int64Value(24),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(false),
IPv6Gateway: types.StringValue("gateway"),
IPv6Prefix: types.StringValue("prefix"),
},
&iaas.CreateNetworkPayload{
Name: utils.Ptr("name"),
AddressFamily: &iaas.CreateNetworkAddressFamily{
Ipv6: &iaas.CreateNetworkIPv6Body{
Nameservers: nil,
PrefixLength: utils.Ptr(int64(24)),
Gateway: iaas.NewNullableString(utils.Ptr("gateway")),
Prefix: utils.Ptr("prefix"),
},
},
Labels: &map[string]interface{}{
"key": "value",
},
Routed: utils.Ptr(false),
},
true,
},
{
"ipv6_nameserver_empty_list",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListValueMust(types.StringType, []attr.Value{}),
IPv6PrefixLength: types.Int64Value(24),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(false),
IPv6Gateway: types.StringValue("gateway"),
IPv6Prefix: types.StringValue("prefix"),
},
&iaas.CreateNetworkPayload{
Name: utils.Ptr("name"),
AddressFamily: &iaas.CreateNetworkAddressFamily{
Ipv6: &iaas.CreateNetworkIPv6Body{
Nameservers: utils.Ptr([]string{}),
PrefixLength: utils.Ptr(int64(24)),
Gateway: iaas.NewNullableString(utils.Ptr("gateway")),
Prefix: utils.Ptr("prefix"),
},
},
Labels: &map[string]interface{}{
"key": "value",
},
Routed: utils.Ptr(false),
},
true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
@ -670,6 +730,66 @@ func TestToUpdatePayload(t *testing.T) {
},
true,
},
{
"ipv6_nameserver_null",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListNull(types.StringType),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(true),
IPv6Gateway: types.StringValue("gateway"),
},
model.Model{
ProjectId: types.StringValue("pid"),
NetworkId: types.StringValue("nid"),
Labels: types.MapNull(types.StringType),
},
&iaas.PartialUpdateNetworkPayload{
Name: utils.Ptr("name"),
AddressFamily: &iaas.UpdateNetworkAddressFamily{
Ipv6: &iaas.UpdateNetworkIPv6Body{
Nameservers: nil,
Gateway: iaas.NewNullableString(utils.Ptr("gateway")),
},
},
Labels: &map[string]interface{}{
"key": "value",
},
},
true,
},
{
"ipv6_nameserver_empty_list",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListValueMust(types.StringType, []attr.Value{}),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(true),
IPv6Gateway: types.StringValue("gateway"),
},
model.Model{
ProjectId: types.StringValue("pid"),
NetworkId: types.StringValue("nid"),
Labels: types.MapNull(types.StringType),
},
&iaas.PartialUpdateNetworkPayload{
Name: utils.Ptr("name"),
AddressFamily: &iaas.UpdateNetworkAddressFamily{
Ipv6: &iaas.UpdateNetworkIPv6Body{
Nameservers: &[]string{},
Gateway: iaas.NewNullableString(utils.Ptr("gateway")),
},
},
Labels: &map[string]interface{}{
"key": "value",
},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {

View file

@ -389,23 +389,34 @@ func toCreatePayload(ctx context.Context, model *networkModel.Model) (*iaasalpha
return nil, fmt.Errorf("nil model")
}
modelIPv6Nameservers := []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
var modelIPv6Nameservers []string
// Is true when IPv6Nameservers is not null or unset
if !utils.IsUndefined(model.IPv6Nameservers) {
// If ipv6Nameservers is empty, modelIPv6Nameservers will be set to an empty slice.
// empty slice != nil slice. Empty slice will result in an empty list in the payload []. Nil slice will result in a payload without the property set
modelIPv6Nameservers = []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
var ipv6Body *iaasalpha.CreateNetworkIPv6
if !utils.IsUndefined(model.IPv6PrefixLength) {
ipv6Body = &iaasalpha.CreateNetworkIPv6{
CreateNetworkIPv6WithPrefixLength: &iaasalpha.CreateNetworkIPv6WithPrefixLength{
Nameservers: &modelIPv6Nameservers,
PrefixLength: conversion.Int64ValueToPointer(model.IPv6PrefixLength),
},
}
// IPv6 nameservers should only be set, if it contains any value. If the slice is nil, it should NOT be set.
// Setting it to a nil slice would result in a payload, where nameservers is set to null in the json payload,
// but it should actually be unset. Setting it to "null" will result in an error, because it's NOT nullable.
if modelIPv6Nameservers != nil {
ipv6Body.CreateNetworkIPv6WithPrefixLength.Nameservers = &modelIPv6Nameservers
}
} else if !utils.IsUndefined(model.IPv6Prefix) {
var gateway *iaasalpha.NullableString
if model.NoIPv6Gateway.ValueBool() {
@ -416,11 +427,16 @@ func toCreatePayload(ctx context.Context, model *networkModel.Model) (*iaasalpha
ipv6Body = &iaasalpha.CreateNetworkIPv6{
CreateNetworkIPv6WithPrefix: &iaasalpha.CreateNetworkIPv6WithPrefix{
Gateway: gateway,
Nameservers: &modelIPv6Nameservers,
Prefix: conversion.StringValueToPointer(model.IPv6Prefix),
Gateway: gateway,
Prefix: conversion.StringValueToPointer(model.IPv6Prefix),
},
}
// IPv6 nameservers should only be set, if it contains any value. If the slice is nil, it should NOT be set.
// Setting it to a nil slice would result in a payload, where nameservers is set to null in the json payload,
// but it should actually be unset. Setting it to "null" will result in an error, because it's NOT nullable.
if modelIPv6Nameservers != nil {
ipv6Body.CreateNetworkIPv6WithPrefix.Nameservers = &modelIPv6Nameservers
}
}
modelIPv4Nameservers := []string{}
@ -487,19 +503,29 @@ func toUpdatePayload(ctx context.Context, model, stateModel *networkModel.Model)
return nil, fmt.Errorf("nil model")
}
modelIPv6Nameservers := []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
var modelIPv6Nameservers []string
// Is true when IPv6Nameservers is not null or unset
if !utils.IsUndefined(model.IPv6Nameservers) {
// If ipv6Nameservers is empty, modelIPv6Nameservers will be set to an empty slice.
// empty slice != nil slice. Empty slice will result in an empty list in the payload []. Nil slice will result in a payload without the property set
modelIPv6Nameservers = []string{}
for _, ipv6ns := range model.IPv6Nameservers.Elements() {
ipv6NameserverString, ok := ipv6ns.(types.String)
if !ok {
return nil, fmt.Errorf("type assertion failed")
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
modelIPv6Nameservers = append(modelIPv6Nameservers, ipv6NameserverString.ValueString())
}
var ipv6Body *iaasalpha.UpdateNetworkIPv6Body
if !(model.IPv6Nameservers.IsNull() || model.IPv6Nameservers.IsUnknown()) {
ipv6Body = &iaasalpha.UpdateNetworkIPv6Body{
Nameservers: &modelIPv6Nameservers,
if modelIPv6Nameservers != nil || !utils.IsUndefined(model.NoIPv6Gateway) || !utils.IsUndefined(model.IPv6Gateway) {
ipv6Body = &iaasalpha.UpdateNetworkIPv6Body{}
// IPv6 nameservers should only be set, if it contains any value. If the slice is nil, it should NOT be set.
// Setting it to a nil slice would result in a payload, where nameservers is set to null in the json payload,
// but it should actually be unset. Setting it to "null" will result in an error, because it's NOT nullable.
if modelIPv6Nameservers != nil {
ipv6Body.Nameservers = &modelIPv6Nameservers
}
if model.NoIPv6Gateway.ValueBool() {

View file

@ -492,6 +492,62 @@ func TestToCreatePayload(t *testing.T) {
},
true,
},
{
"ipv6_nameserver_null",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListNull(types.StringType),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(false),
IPv6Gateway: types.StringValue("gateway"),
IPv6Prefix: types.StringValue("prefix"),
},
&iaasalpha.CreateNetworkPayload{
Name: utils.Ptr("name"),
Ipv6: &iaasalpha.CreateNetworkIPv6{
CreateNetworkIPv6WithPrefix: &iaasalpha.CreateNetworkIPv6WithPrefix{
Nameservers: nil,
Gateway: iaasalpha.NewNullableString(utils.Ptr("gateway")),
Prefix: utils.Ptr("prefix"),
},
},
Labels: &map[string]interface{}{
"key": "value",
},
Routed: utils.Ptr(false),
},
true,
},
{
"ipv6_nameserver_empty_list",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListValueMust(types.StringType, []attr.Value{}),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(false),
IPv6Gateway: types.StringValue("gateway"),
IPv6Prefix: types.StringValue("prefix"),
},
&iaasalpha.CreateNetworkPayload{
Name: utils.Ptr("name"),
Ipv6: &iaasalpha.CreateNetworkIPv6{
CreateNetworkIPv6WithPrefix: &iaasalpha.CreateNetworkIPv6WithPrefix{
Nameservers: utils.Ptr([]string{}),
Gateway: iaasalpha.NewNullableString(utils.Ptr("gateway")),
Prefix: utils.Ptr("prefix"),
},
},
Labels: &map[string]interface{}{
"key": "value",
},
Routed: utils.Ptr(false),
},
true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
@ -686,6 +742,62 @@ func TestToUpdatePayload(t *testing.T) {
},
true,
},
{
"ipv6_nameserver_null",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListNull(types.StringType),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(true),
IPv6Gateway: types.StringValue("gateway"),
},
model.Model{
ProjectId: types.StringValue("pid"),
NetworkId: types.StringValue("nid"),
Labels: types.MapNull(types.StringType),
},
&iaasalpha.PartialUpdateNetworkPayload{
Name: utils.Ptr("name"),
Ipv6: &iaasalpha.UpdateNetworkIPv6Body{
Nameservers: nil,
Gateway: iaasalpha.NewNullableString(utils.Ptr("gateway")),
},
Labels: &map[string]interface{}{
"key": "value",
},
},
true,
},
{
"ipv6_nameserver_empty_list",
&model.Model{
Name: types.StringValue("name"),
IPv6Nameservers: types.ListValueMust(types.StringType, []attr.Value{}),
Labels: types.MapValueMust(types.StringType, map[string]attr.Value{
"key": types.StringValue("value"),
}),
Routed: types.BoolValue(true),
IPv6Gateway: types.StringValue("gateway"),
},
model.Model{
ProjectId: types.StringValue("pid"),
NetworkId: types.StringValue("nid"),
Labels: types.MapNull(types.StringType),
},
&iaasalpha.PartialUpdateNetworkPayload{
Name: utils.Ptr("name"),
Ipv6: &iaasalpha.UpdateNetworkIPv6Body{
Nameservers: utils.Ptr([]string{}),
Gateway: iaasalpha.NewNullableString(utils.Ptr("gateway")),
},
Labels: &map[string]interface{}{
"key": "value",
},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {