Skip to content

Commit e3bfe03

Browse files
Mia-Crossyfodil
andcommitted
feat(redis): read cluster's private IPs
Co-authored-by: Yacine FODIL <[email protected]>
1 parent 8801985 commit e3bfe03

File tree

7 files changed

+2425
-3130
lines changed

7 files changed

+2425
-3130
lines changed

docs/resources/redis_cluster.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ the form `{zone}/{id}`, e.g. `fr-par-1/11111111-1111-1111-1111-111111111111`
195195
- `endpoint_id` - The ID of the endpoint.
196196
- `zone` - The zone of the Private Network.
197197

198+
- `private_ip` - The list of private IPv4 addresses associated with the resource.
199+
- `id` - The ID of the IPv4 address resource.
200+
- `address` - The private IPv4 address.
201+
198202
- `created_at` - The date and time of creation of the Redis™ cluster.
199203
- `updated_at` - The date and time of the last update of the Redis™ cluster.
200204
- `certificate` - The PEM of the certificate used by redis, only when `tls_enabled` is true

internal/services/ipam/helpers.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ipam
22

33
import (
4+
"context"
5+
"fmt"
46
"net"
57
"time"
68

@@ -65,3 +67,63 @@ func diffSuppressFuncStandaloneIPandCIDR(_, oldValue, newValue string, _ *schema
6567

6668
return false
6769
}
70+
71+
type GetResourcePrivateIPsOptions struct {
72+
ResourceType *ipam.ResourceType
73+
ResourceID *string
74+
ResourceName *string
75+
PrivateNetworkID *string
76+
}
77+
78+
// GetResourcePrivateIPs fetches the private IP addresses of a resource in a private network.
79+
func GetResourcePrivateIPs(ctx context.Context, m interface{}, region scw.Region, opts *GetResourcePrivateIPsOptions) ([]map[string]interface{}, error) {
80+
ipamAPI := ipam.NewAPI(meta.ExtractScwClient(m))
81+
82+
req := &ipam.ListIPsRequest{
83+
Region: region,
84+
}
85+
86+
if opts != nil {
87+
if opts.PrivateNetworkID != nil {
88+
req.PrivateNetworkID = opts.PrivateNetworkID
89+
}
90+
91+
if opts.ResourceID != nil {
92+
req.ResourceID = opts.ResourceID
93+
}
94+
95+
if opts.ResourceName != nil {
96+
req.ResourceName = opts.ResourceName
97+
}
98+
99+
if opts.ResourceType != nil {
100+
req.ResourceType = *opts.ResourceType
101+
}
102+
}
103+
104+
resp, err := ipamAPI.ListIPs(req, scw.WithContext(ctx))
105+
if err != nil {
106+
return nil, fmt.Errorf("error fetching IPs from IPAM: %w", err)
107+
}
108+
109+
if len(resp.IPs) == 0 {
110+
return nil, nil
111+
}
112+
113+
ipList := make([]map[string]interface{}, 0, len(resp.IPs))
114+
115+
for _, ip := range resp.IPs {
116+
ipNet := ip.Address
117+
if ipNet.IP == nil {
118+
continue
119+
}
120+
121+
ipMap := map[string]interface{}{
122+
"id": regional.NewIDString(region, ip.ID),
123+
"address": ipNet.IP.String(),
124+
}
125+
ipList = append(ipList, ipMap)
126+
}
127+
128+
return ipList, nil
129+
}

internal/services/ipam/testdata/data-source-ipam-ips-redis-cluster.cassette.yaml

Lines changed: 690 additions & 788 deletions
Large diffs are not rendered by default.

internal/services/redis/cluster.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
1212
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1313
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
14+
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
1415
"github.com/scaleway/scaleway-sdk-go/api/redis/v1"
1516
"github.com/scaleway/scaleway-sdk-go/scw"
1617
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
@@ -19,6 +20,7 @@ import (
1920
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
2021
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
2122
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
23+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
2224
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
2325
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
2426
)
@@ -193,6 +195,25 @@ func ResourceCluster() *schema.Resource {
193195
},
194196
},
195197
},
198+
"private_ips": {
199+
Type: schema.TypeList,
200+
Computed: true,
201+
Description: "List of private IP addresses associated with the resource",
202+
Elem: &schema.Resource{
203+
Schema: map[string]*schema.Schema{
204+
"id": {
205+
Type: schema.TypeString,
206+
Computed: true,
207+
Description: "The ID of the IP address resource",
208+
},
209+
"address": {
210+
Type: schema.TypeString,
211+
Computed: true,
212+
Description: "The private IP address",
213+
},
214+
},
215+
},
216+
},
196217
"certificate": {
197218
Type: schema.TypeString,
198219
Computed: true,
@@ -344,11 +365,46 @@ func ResourceClusterRead(ctx context.Context, d *schema.ResourceData, m interfac
344365
}
345366

346367
// set endpoints
368+
var allPrivateIPs []map[string]interface{}
369+
347370
pnI, pnExists := flattenPrivateNetwork(cluster.Endpoints)
348371
if pnExists {
349372
_ = d.Set("private_network", pnI)
373+
374+
privateNetworkIDs := []string(nil)
375+
376+
for _, endpoint := range cluster.Endpoints {
377+
if endpoint.PrivateNetwork != nil {
378+
privateNetworkIDs = append(privateNetworkIDs, endpoint.PrivateNetwork.ID)
379+
}
380+
}
381+
382+
resourceType := ipamAPI.ResourceTypeRedisCluster
383+
384+
region, err := zone.Region()
385+
if err != nil {
386+
return diag.FromErr(err)
387+
}
388+
389+
for _, privateNetworkID := range privateNetworkIDs {
390+
opts := &ipam.GetResourcePrivateIPsOptions{
391+
ResourceType: &resourceType,
392+
PrivateNetworkID: &privateNetworkID,
393+
ResourceID: &cluster.ID,
394+
}
395+
396+
privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
397+
if err != nil {
398+
return diag.FromErr(err)
399+
}
400+
401+
if privateIPs != nil {
402+
allPrivateIPs = append(allPrivateIPs, privateIPs...)
403+
}
404+
}
350405
}
351406

407+
_ = d.Set("private_ips", allPrivateIPs)
352408
_ = d.Set("public_network", flattenPublicNetwork(cluster.Endpoints))
353409

354410
if cluster.TLSEnabled {

internal/services/redis/cluster_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ func TestAccCluster_MigrateClusterSizeWithIPAMEndpoint(t *testing.T) {
216216
resource.TestCheckResourceAttr("scaleway_redis_cluster.main", "tls_enabled", "true"),
217217
resource.TestCheckResourceAttrPair("scaleway_redis_cluster.main", "private_network.0.id", "scaleway_vpc_private_network.private_network", "id"),
218218
acctest.CheckResourceIDChanged("scaleway_redis_cluster.main", &clusterID),
219+
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_ips.0.id"),
220+
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_ips.0.address"),
221+
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_ips.1.id"),
222+
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_ips.1.address"),
223+
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_ips.2.id"),
224+
resource.TestCheckResourceAttrSet("scaleway_redis_cluster.main", "private_ips.2.address"),
219225
),
220226
},
221227
},

0 commit comments

Comments
 (0)