Skip to content

Commit 48ac8d5

Browse files
authored
feat(ipam): add support for ip reverse dns (#2377)
* feat(ipam): add support for ip reverse dns * fix * lint
1 parent 59ca567 commit 48ac8d5

12 files changed

+2369
-23
lines changed

docs/resources/ipam_ip.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ In addition to all arguments above, the following attributes are exported:
9898
- `type` - The type of resource the IP is attached to.
9999
- `name` - The name of the resource the IP is attached to.
100100
- `mac_address` - The MAC Address of the resource the IP is attached to.
101+
- `reverses` - The reverses DNS for this IP.
102+
- `hostname` The reverse domain name.
103+
- `address` The IP corresponding to the hostname.
101104
- `created_at` - Date and time of IP's creation (RFC 3339 format).
102105
- `updated_at` - Date and time of IP's last update (RFC 3339 format).
103106
- `zone` - The zone of the IP.

docs/resources/ipam_ip_reverse_dns.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
subcategory: "IPAM"
3+
page_title: "Scaleway: scaleway_ipam_ip_reverse_dns"
4+
---
5+
6+
# Resource: scaleway_ipam_ip_reverse_dns
7+
8+
Manages Scaleway IPAM IP Reverse DNS.
9+
10+
## Example Usage
11+
12+
```terraform
13+
resource "scaleway_instance_ip" "ip01" {
14+
type = "routed_ipv6"
15+
}
16+
17+
resource "scaleway_instance_server" "srv01" {
18+
name = "tf-tests-instance-server-ips"
19+
ip_ids = [scaleway_instance_ip.ip01.id]
20+
image = "ubuntu_jammy"
21+
type = "PRO2-XXS"
22+
state = "stopped"
23+
}
24+
25+
data "scaleway_ipam_ip" "ipam01" {
26+
resource {
27+
id = scaleway_instance_server.srv01.id
28+
type = "instance_server"
29+
}
30+
type = "ipv6"
31+
}
32+
33+
resource "scaleway_domain_record" "tf_AAAA" {
34+
dns_zone = "example.com"
35+
name = ""
36+
type = "AAAA"
37+
data = cidrhost(data.scaleway_ipam_ip.ipam01.address_cidr, 42)
38+
ttl = 3600
39+
priority = 1
40+
}
41+
42+
resource "scaleway_ipam_ip_reverse_dns" "base" {
43+
ipam_ip_id = data.scaleway_ipam_ip.ipam01.id
44+
45+
hostname = "example.com"
46+
address = cidrhost(data.scaleway_ipam_ip.ipam01.address_cidr, 42)
47+
}
48+
```
49+
50+
## Argument Reference
51+
52+
The following arguments are supported:
53+
54+
- `ipam_ip_id` - (Required) The IPAM IP ID.
55+
- `hostname` - (Required) The reverse domain name.
56+
- `address` - (Required) The IP corresponding to the hostname.
57+
- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) of the IP reverse DNS.
58+
59+
## Attributes Reference
60+
61+
In addition to all arguments above, the following attributes are exported:
62+
63+
- `id` - The ID of the IPAM IP for which the DNS reverse is configured.
64+
65+
~> **Important:** IPAM IPs' IDs are [regional](../guides/regions_and_zones.md#resource-ids), which means they are of the form `{region}/{id}`, e.g. `fr-par/11111111-1111-1111-1111-111111111111
66+
67+
## Import
68+
69+
IPAM IP reverse DNS can be imported using the `{region}/{id}`, e.g.
70+
71+
```bash
72+
$ terraform import scaleway_ipam_ip_reverse_dns.main fr-par/11111111-1111-1111-1111-111111111111
73+
```

docs/resources/vpc_public_gateway_ip_reverse_dns.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ resource "scaleway_vpc_public_gateway_ip_reverse_dns" "main" {
3333
The following arguments are supported:
3434

3535
- `gateway_ip_id` - (Required) The public gateway IP ID
36-
- `reverse` - (Optional) The reverse domain name for this IP address
36+
- `reverse` - (Required) The reverse domain name for this IP address
3737
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the IP should be reserved.
3838

3939
## Attributes Reference
@@ -50,5 +50,5 @@ In addition to all arguments above, the following attributes are exported:
5050
Public gateway IPs reverse DNS can be imported using the `{zone}/{id}`, e.g.
5151

5252
```bash
53-
$ terraform import scaleway_vpc_public_gateway_ip_reverse_dns.reverse.main fr-par-1/11111111-1111-1111-1111-111111111111
53+
$ terraform import scaleway_vpc_public_gateway_ip_reverse_dns.reverse fr-par-1/11111111-1111-1111-1111-111111111111
5454
```

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/nats-io/jwt/v2 v2.5.3
1717
github.com/nats-io/nats.go v1.31.0
1818
github.com/robfig/cron/v3 v3.0.1
19-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22.0.20240109155607-70eec6dc9637
19+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22.0.20240111155519-dc916e73b792
2020
github.com/stretchr/testify v1.8.4
2121
)
2222

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
186186
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
187187
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
188188
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
189-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22.0.20240109155607-70eec6dc9637 h1:F/EUOngL9fqQsi3JHn8S6n8oJasOCFk5J/76D+n3s2g=
190-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22.0.20240109155607-70eec6dc9637/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
189+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22.0.20240111155519-dc916e73b792 h1:BzcfWlk1hgYSoASs21qalFTORNwK3fK8x5f4PcsOp/I=
190+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22.0.20240111155519-dc916e73b792/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
191191
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
192192
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
193193
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=

scaleway/helpers_ipam.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ package scaleway
33
import (
44
"net"
55
"strings"
6+
"time"
67

78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
89
ipam "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
910
"github.com/scaleway/scaleway-sdk-go/scw"
1011
"github.com/scaleway/scaleway-sdk-go/validation"
1112
)
1213

14+
const (
15+
defaultIPAMIPReverseDNSTimeout = 10 * time.Minute
16+
)
17+
1318
// ipamAPIWithRegion returns a new ipam API and the region
1419
func ipamAPIWithRegion(d *schema.ResourceData, m interface{}) (*ipam.API, scw.Region, error) {
1520
meta := m.(*Meta)
@@ -93,6 +98,25 @@ func flattenIPResource(resource *ipam.Resource) interface{} {
9398
}
9499
}
95100

101+
func flattenIPReverse(reverse *ipam.Reverse) interface{} {
102+
if reverse == nil {
103+
return nil
104+
}
105+
106+
return map[string]interface{}{
107+
"hostname": reverse.Hostname,
108+
"address": flattenIPPtr(reverse.Address),
109+
}
110+
}
111+
112+
func flattenIPReverses(reverses []*ipam.Reverse) interface{} {
113+
rawReverses := make([]interface{}, 0, len(reverses))
114+
for _, reverse := range reverses {
115+
rawReverses = append(rawReverses, flattenIPReverse(reverse))
116+
}
117+
return rawReverses
118+
}
119+
96120
func checkSubnetIDInFlattenedSubnets(subnetID string, flattenedSubnets interface{}) bool {
97121
for _, subnet := range flattenedSubnets.([]map[string]interface{}) {
98122
if subnet["id"].(string) == subnetID {

scaleway/helpers_vpcgw.go

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package scaleway
22

33
import (
44
"context"
5-
"errors"
65
"time"
76

87
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -93,30 +92,14 @@ func waitForDHCPEntries(ctx context.Context, api *vpcgw.API, zone scw.Zone, gate
9392
return dhcpEntries, err
9493
}
9594

96-
func isGatewayReverseDNSResolveError(err error) bool {
97-
invalidArgError := &scw.InvalidArgumentsError{}
98-
99-
if !errors.As(err, &invalidArgError) {
100-
return false
101-
}
102-
103-
for _, fields := range invalidArgError.Details {
104-
if fields.ArgumentName == "reverse" {
105-
return true
106-
}
107-
}
108-
109-
return false
110-
}
111-
11295
func retryUpdateGatewayReverseDNS(ctx context.Context, api *vpcgw.API, req *vpcgw.UpdateIPRequest, timeout time.Duration) error {
11396
timeoutChannel := time.After(timeout)
11497

11598
for {
11699
select {
117100
case <-time.After(defaultVPCGatewayRetry):
118101
_, err := api.UpdateIP(req, scw.WithContext(ctx))
119-
if err != nil && isGatewayReverseDNSResolveError(err) {
102+
if err != nil && isIPReverseDNSResolveError(err) {
120103
continue
121104
}
122105
return err

scaleway/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
136136
"scaleway_iot_route": resourceScalewayIotRoute(),
137137
"scaleway_iot_network": resourceScalewayIotNetwork(),
138138
"scaleway_ipam_ip": resourceScalewayIPAMIP(),
139+
"scaleway_ipam_ip_reverse_dns": resourceScalewayIPAMIPReverseDNS(),
139140
"scaleway_job_definition": resourceScalewayJobDefinition(),
140141
"scaleway_k8s_cluster": resourceScalewayK8SCluster(),
141142
"scaleway_k8s_pool": resourceScalewayK8SPool(),

scaleway/resource_ipam_ip.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ func resourceScalewayIPAMIP() *schema.Resource {
107107
},
108108
},
109109
},
110+
"reverses": {
111+
Type: schema.TypeList,
112+
Computed: true,
113+
Description: "The reverses DNS for this IP",
114+
Elem: &schema.Resource{
115+
Schema: map[string]*schema.Schema{
116+
"hostname": {
117+
Type: schema.TypeString,
118+
Computed: true,
119+
Description: "The reverse domain name",
120+
},
121+
"address": {
122+
Type: schema.TypeString,
123+
Computed: true,
124+
Description: "The IP corresponding to the hostname",
125+
},
126+
},
127+
},
128+
},
110129
"created_at": {
111130
Type: schema.TypeString,
112131
Computed: true,
@@ -229,6 +248,7 @@ func resourceScalewayIPAMIPRead(ctx context.Context, d *schema.ResourceData, met
229248
if len(res.Tags) > 0 {
230249
_ = d.Set("tags", res.Tags)
231250
}
251+
_ = d.Set("reverses", flattenIPReverses(res.Reverses))
232252

233253
return nil
234254
}

0 commit comments

Comments
 (0)