Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dhcp): default values and read #1157

Merged
merged 5 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/resources/vpc_public_gateway_dhcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: |-
# scaleway_vpc_public_gateway_dhcp

Creates and manages Scaleway VPC Public Gateway DHCP.
For more information, see [the documentation](https://developers.scaleway.com/en/products/vpc-gw/api/v1).
For more information, see [the documentation](https://developers.scaleway.com/en/products/vpc-gw/api/v1/#dhcp-c05544).

## Example

Expand All @@ -29,7 +29,7 @@ The following arguments are supported:
- `pool_high` - (Optional) High IP (excluded) of the dynamic address pool. Defaults to the last address of the subnet.
- `enable_dynamic` - (Optional) Whether to enable dynamic pooling of IPs. By turning the dynamic pool off, only pre-existing DHCP reservations will be handed out. Defaults to `true`.
- `valid_lifetime` - (Optional) For how long, in seconds, will DHCP entries will be valid. Defaults to 1h (3600s).
- `renew_timer` - (Optional) After how long, in seconds, a renew will be attempted. Must be 30s lower than `rebind_timer`. Defaults to 50m (3000s).
- `renew_timer` - (Optional) After how long, in seconds, a renewal will be attempted. Must be 30s lower than `rebind_timer`. Defaults to 50m (3000s).
- `rebind_timer` - (Optional) After how long, in seconds, a DHCP client will query for a new lease if previous renews fail. Must be 30s lower than `valid_lifetime`. Defaults to 51m (3060s).
- `push_default_route` - (Optional) Whether the gateway should push a default route to DHCP clients or only hand out IPs. Defaults to `true`.
- `push_dns_server` - (Optional) Whether the gateway should push custom DNS servers to clients. This allows for instance hostname -> IP resolution. Defaults to `true`.
Expand Down
8 changes: 8 additions & 0 deletions scaleway/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,14 @@ func flattenSliceStringPtr(s []*string) interface{} {
return res
}

func flattenSliceString(s []string) interface{} {
res := make([]interface{}, 0, len(s))
for _, strPtr := range s {
res = append(res, strPtr)
}
return res
}

func flattenSliceIDs(certificates []string, zone scw.Zone) interface{} {
res := []interface{}(nil)
for _, certificateID := range certificates {
Expand Down
147 changes: 108 additions & 39 deletions scaleway/resource_vpc_public_gateway_dhcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
vpcgw "github.com/scaleway/scaleway-sdk-go/api/vpcgw/v1"
"github.com/scaleway/scaleway-sdk-go/api/vpcgw/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

Expand All @@ -35,7 +35,7 @@ func resourceScalewayVPCPublicGatewayDHCP() *schema.Resource {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Address: address of the DHCP server. This will be the gateway's address in the private network. Defaults to the first address of the subnet",
Description: "The address of the DHCP server. This will be the gateway's address in the private network. Defaults to the first address of the subnet",
},
"pool_low": {
Type: schema.TypeString,
Expand All @@ -54,7 +54,7 @@ func resourceScalewayVPCPublicGatewayDHCP() *schema.Resource {
"enable_dynamic": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Computed: true,
Description: "Whether to enable dynamic pooling of IPs. By turning the dynamic pool off, only pre-existing DHCP reservations will be handed out. Defaults to true.",
},
"valid_lifetime": {
Expand All @@ -78,13 +78,13 @@ func resourceScalewayVPCPublicGatewayDHCP() *schema.Resource {
"push_default_route": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Whether the gateway should push a default route to DHCP clients or only hand out IPs. Defaults to true",
Computed: true,
Description: "Whether the gateway should push a default route to DHCP clients or only hand out IPs. Defaults to true.",
},
"push_dns_server": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Computed: true,
Description: "Whether the gateway should push custom DNS servers to clients. This allows for instance hostname -> IP resolution. Defaults to true.",
},
"dns_server_override": {
Expand All @@ -93,15 +93,15 @@ func resourceScalewayVPCPublicGatewayDHCP() *schema.Resource {
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "Override the DNS server list pushed to DHCP clients, instead of the gateway itself",
Description: "Override the DNS server list pushed to DHCP clients, instead of the gateway itself.",
},
"dns_search": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "Additional DNS search paths",
Description: "Additional DNS search paths.",
},
"dns_local_name": {
Type: schema.TypeString,
Expand All @@ -113,12 +113,12 @@ func resourceScalewayVPCPublicGatewayDHCP() *schema.Resource {
"created_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the creation of the public gateway",
Description: "The date and time of the creation of the public gateway.",
},
"updated_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the last update of the public gateway",
Description: "The date and time of the last update of the public gateway.",
},
},
}
Expand All @@ -135,39 +135,57 @@ func resourceScalewayVPCPublicGatewayDHCPCreate(ctx context.Context, d *schema.R
return diag.FromErr(err)
}
req := &vpcgw.CreateDHCPRequest{
Zone: zone,
ProjectID: d.Get("project_id").(string),
Subnet: subnet,
EnableDynamic: expandBoolPtr(d.Get("enable_dynamic")),
PushDefaultRoute: expandBoolPtr(d.Get("push_default_route")),
PushDNSServer: expandBoolPtr(d.Get("push_dns_servers")),
DNSServersOverride: expandStringsPtr(d.Get("dns_servers_override")),
DNSSearch: expandStringsPtr(d.Get("dns_search")),
DNSLocalName: expandStringPtr(d.Get("dns_local_name")),
Zone: zone,
ProjectID: d.Get("project_id").(string),
Subnet: subnet,
}

if pushDefaultRoute, ok := d.GetOk("push_default_route"); ok {
req.PushDefaultRoute = expandBoolPtr(pushDefaultRoute)
}

if pushDNServer, ok := d.GetOk("push_dns_server"); ok {
req.PushDNSServer = expandBoolPtr(pushDNServer)
}

if enableDynamic, ok := d.GetOk("enable_dynamic"); ok {
req.EnableDynamic = expandBoolPtr(enableDynamic)
}

if dnsServerOverride, ok := d.GetOk("dns_servers_override"); ok {
req.DNSServersOverride = expandStringsPtr(dnsServerOverride)
}

if dnsSearch, ok := d.GetOk("dns_search"); ok {
req.DNSSearch = expandStringsPtr(dnsSearch)
}

if dsnLocalName, ok := d.GetOk("dns_local_name"); ok {
req.DNSLocalName = expandStringPtr(dsnLocalName)
}

if address, ok := d.GetOk("address"); ok {
req.Address = scw.IPPtr(net.ParseIP(address.(string)))
}

if renewTimer, ok := d.GetOk("renew_timer"); ok {
req.RenewTimer = &scw.Duration{Seconds: renewTimer.(int64)}
req.RenewTimer = &scw.Duration{Seconds: int64(renewTimer.(int))}
}

if validLifetime, ok := d.GetOk("valid_lifetime"); ok {
req.ValidLifetime = &scw.Duration{Seconds: validLifetime.(int64)}
req.ValidLifetime = &scw.Duration{Seconds: int64(validLifetime.(int))}
}

if rebindTimer, ok := d.GetOk("rebind_timer"); ok {
req.RebindTimer = &scw.Duration{Seconds: rebindTimer.(int64)}
req.RebindTimer = &scw.Duration{Seconds: int64(rebindTimer.(int))}
}

if poolLow, ok := d.GetOk("pool_low"); ok {
req.PoolLow = scw.IPPtr(net.ParseIP(poolLow.(string)))
}

if poolHigh, ok := d.GetOk("pool_high"); ok {
req.PoolLow = scw.IPPtr(net.ParseIP(poolHigh.(string)))
req.PoolHigh = scw.IPPtr(net.ParseIP(poolHigh.(string)))
}

res, err := vpcgwAPI.CreateDHCP(req, scw.WithContext(ctx))
Expand Down Expand Up @@ -201,8 +219,8 @@ func resourceScalewayVPCPublicGatewayDHCPRead(ctx context.Context, d *schema.Res
_ = d.Set("address", dhcp.Address.String())
_ = d.Set("created_at", dhcp.CreatedAt.Format(time.RFC3339))
_ = d.Set("dns_local_name", dhcp.DNSLocalName)
_ = d.Set("dns_search", dhcp.DNSSearch)
_ = d.Set("dns_server_override", dhcp.DNSServersOverride)
_ = d.Set("dns_search", flattenSliceString(dhcp.DNSSearch))
_ = d.Set("dns_server_override", flattenSliceString(dhcp.DNSServersOverride))
_ = d.Set("enable_dynamic", dhcp.EnableDynamic)
_ = d.Set("organization_id", dhcp.OrganizationID)
_ = d.Set("pool_high", dhcp.PoolLow.String())
Expand All @@ -226,26 +244,77 @@ func resourceScalewayVPCPublicGatewayDHCPUpdate(ctx context.Context, d *schema.R
return diag.FromErr(err)
}

if d.HasChangesExcept("enable_dynamic", "push_default_route", "push_dns_servers", "dns_servers_override",
"dns_search", "dns_local_name") {
req := &vpcgw.UpdateDHCPRequest{
DHCPID: ID,
Zone: zone,
EnableDynamic: expandBoolPtr(d.Get("enable_dynamic")),
PushDefaultRoute: expandBoolPtr(d.Get("push_default_route")),
PushDNSServer: expandBoolPtr(d.Get("push_dns_servers")),
DNSServersOverride: expandStringsPtr(d.Get("dns_servers_override")),
DNSSearch: expandStringsPtr(d.Get("dns_search")),
DNSLocalName: expandStringPtr(d.Get("dns_local_name")),
}
req := &vpcgw.UpdateDHCPRequest{
DHCPID: ID,
Zone: zone,
}

_, err = vpcgwAPI.UpdateDHCP(req, scw.WithContext(ctx))
if subnetRaw, ok := d.GetOk("subnet"); ok {
subnet, err := expandIPNet(subnetRaw.(string))
if err != nil {
return diag.FromErr(err)
}
req.Subnet = &subnet
}

if ok := d.HasChange("address"); ok {
req.Address = scw.IPPtr(net.ParseIP(d.Get("address").(string)))
}

if ok := d.HasChange("push_dns_server"); ok {
req.PushDNSServer = expandBoolPtr(d.Get("push_dns_server"))
}

if ok := d.HasChange("enable_dynamic"); ok {
req.EnableDynamic = expandBoolPtr(d.Get("enable_dynamic"))
}

if ok := d.HasChange("push_default_route"); ok {
req.PushDefaultRoute = expandBoolPtr(d.Get("push_default_route"))
}

if ok := d.HasChange("dns_local_name"); ok {
req.DNSLocalName = expandStringPtr(d.Get("dns_local_name"))
}

if ok := d.HasChange("renew_timer"); ok {
req.RenewTimer = &scw.Duration{Seconds: int64(d.Get("renew_timer").(int))}
}

if ok := d.HasChange("valid_lifetime"); ok {
req.ValidLifetime = &scw.Duration{Seconds: int64(d.Get("valid_lifetime").(int))}
}

if ok := d.HasChange("rebind_timer"); ok {
req.RebindTimer = &scw.Duration{Seconds: int64(d.Get("rebind_timer").(int))}
}

if ok := d.HasChange("pool_low"); ok {
req.PoolLow = scw.IPPtr(net.ParseIP(d.Get("pool_low").(string)))
}

if ok := d.HasChange("pool_high"); ok {
req.PoolHigh = scw.IPPtr(net.ParseIP(d.Get("pool_high").(string)))
}

if d.HasChangesExcept("dns_servers_override") {
if dnsServerOverride, ok := d.GetOk("dns_servers_override"); ok {
req.DNSServersOverride = expandStringsPtr(dnsServerOverride)
}
}

if d.HasChangesExcept("dns_search") {
if dnsSearch, ok := d.GetOk("dns_search"); ok {
req.DNSSearch = expandStringsPtr(dnsSearch)
}
}

_, err = vpcgwAPI.UpdateDHCP(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

return resourceScalewayVPCPublicGatewayRead(ctx, d, meta)
return resourceScalewayVPCPublicGatewayDHCPRead(ctx, d, meta)
}

func resourceScalewayVPCPublicGatewayDHCPDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
Expand Down
61 changes: 49 additions & 12 deletions scaleway/resource_vpc_public_gateway_dhcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,54 @@ func TestAccScalewayVPCPublicGatewayDHCP_Basic(t *testing.T) {
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayVPCPublicGatewayDHCPExists(tt, "scaleway_vpc_public_gateway_dhcp.main"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "subnet", "192.168.1.0/24"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "enable_dynamic", "true"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "valid_lifetime", "3600"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "renew_timer", "3000"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "rebind_timer", "3060"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "push_default_route", "true"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "push_dns_server", "true"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "dns_server_override.#", "0"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "dns_search.#", "0"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "dns_local_name"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "pool_low"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "pool_high"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "created_at"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "updated_at"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "zone"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "organization_id"),
),
},
{
Config: `
resource scaleway_vpc_public_gateway_dhcp main {
subnet = "192.168.1.0/24"
valid_lifetime = 3000
renew_timer = 2000
rebind_timer = 2060
push_default_route = false
push_dns_server = false
enable_dynamic = false
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayVPCPublicGatewayDHCPExists(tt, "scaleway_vpc_public_gateway_dhcp.main"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "subnet", "192.168.1.0/24"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "push_default_route", "false"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "push_dns_server", "false"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "enable_dynamic", "false"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "valid_lifetime", "3000"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "renew_timer", "2000"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "rebind_timer", "2060"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "dns_server_override.#", "0"),
resource.TestCheckResourceAttr("scaleway_vpc_public_gateway_dhcp.main", "dns_search.#", "0"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "dns_local_name"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "pool_low"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "pool_high"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "created_at"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "updated_at"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "zone"),
resource.TestCheckResourceAttrSet("scaleway_vpc_public_gateway_dhcp.main", "organization_id"),
),
},
},
Expand All @@ -44,7 +92,7 @@ func testAccCheckScalewayVPCPublicGatewayDHCPExists(tt *TestTools, n string) res
return err
}

dhcp, err := vpcgwAPI.GetDHCP(&vpcgw.GetDHCPRequest{
_, err = vpcgwAPI.GetDHCP(&vpcgw.GetDHCPRequest{
DHCPID: ID,
Zone: zone,
})
Expand All @@ -53,17 +101,6 @@ func testAccCheckScalewayVPCPublicGatewayDHCPExists(tt *TestTools, n string) res
return err
}

// Test default values
if !dhcp.EnableDynamic {
return fmt.Errorf("enable_dynamic is false, should default to true")
}
if !dhcp.PushDefaultRoute {
return fmt.Errorf("push_default_route is false, should default to true")
}
if !dhcp.PushDNSServer {
return fmt.Errorf("push_dns_server is false, should default to true")
}

return nil
}
}
Expand Down
Loading