Skip to content

Commit 63d1ed1

Browse files
Mia-Crossyfodil
andcommitted
feat(instance): private nic: read private IPs
Co-authored-by: Yacine FODIL <[email protected]>
1 parent 8801985 commit 63d1ed1

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

docs/resources/instance_private_nic.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ In addition to all arguments above, the following attributes are exported:
9393
~> **Important:** Instance private NICs' IDs are [zoned](../guides/regions_and_zones.md#resource-ids), which means they are of the form `{zone}/{id}`, e.g. `fr-par-1/11111111-1111-1111-1111-111111111111`
9494

9595
- `mac_address` - The MAC address of the private NIC.
96+
- `private_ip` - The list of private IPv4 addresses associated with the resource.
97+
- `id` - The ID of the IPv4 address resource.
98+
- `address` - The private IPv4 address.
9699

97100
## Import
98101

internal/services/instance/private_nic.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import (
66
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
77
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
88
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
9+
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
910
"github.com/scaleway/scaleway-sdk-go/scw"
1011
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
1112
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
1213
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1314
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1415
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
1516
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
17+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
1618
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
1719
)
1820

@@ -68,6 +70,25 @@ func ResourcePrivateNIC() *schema.Resource {
6870
Description: "IPAM ip list, should be for internal use only",
6971
ForceNew: true,
7072
},
73+
"private_ip": {
74+
Type: schema.TypeList,
75+
Computed: true,
76+
Description: "List of private IPv4 addresses associated with the resource",
77+
Elem: &schema.Resource{
78+
Schema: map[string]*schema.Schema{
79+
"id": {
80+
Type: schema.TypeString,
81+
Computed: true,
82+
Description: "The ID of the IPv4 address resource",
83+
},
84+
"address": {
85+
Type: schema.TypeString,
86+
Computed: true,
87+
Description: "The private IPv4 address",
88+
},
89+
},
90+
},
91+
},
7192
"ipam_ip_ids": {
7293
Type: schema.TypeList,
7394
Elem: &schema.Schema{
@@ -163,6 +184,23 @@ func ResourceInstancePrivateNICRead(ctx context.Context, d *schema.ResourceData,
163184
_ = d.Set("tags", privateNIC.Tags)
164185
}
165186

187+
region, err := zone.Region()
188+
if err != nil {
189+
return diag.FromErr(err)
190+
}
191+
192+
resourceType := ipamAPI.ResourceTypeInstancePrivateNic
193+
opts := &ipam.GetResourcePrivateIPsOptions{
194+
ResourceID: &privateNIC.ID,
195+
ResourceType: &resourceType,
196+
PrivateNetworkID: &privateNIC.PrivateNetworkID,
197+
}
198+
privateIP, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
199+
if err != nil {
200+
return diag.FromErr(err)
201+
}
202+
_ = d.Set("private_ip", privateIP)
203+
166204
return nil
167205
}
168206

internal/services/instance/private_nic_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func TestAccPrivateNIC_Basic(t *testing.T) {
4141
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "mac_address"),
4242
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_network_id"),
4343
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "server_id"),
44+
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ip.0.id"),
45+
resource.TestCheckResourceAttrSet("scaleway_instance_private_nic.nic01", "private_ip.0.address"),
4446
),
4547
},
4648
},

internal/services/ipam/helpers.go

Lines changed: 57 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,58 @@ 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+
if opts.ResourceID != nil {
91+
req.ResourceID = opts.ResourceID
92+
}
93+
if opts.ResourceName != nil {
94+
req.ResourceName = opts.ResourceName
95+
}
96+
if opts.ResourceType != nil {
97+
req.ResourceType = *opts.ResourceType
98+
}
99+
}
100+
101+
resp, err := ipamAPI.ListIPs(req, scw.WithContext(ctx))
102+
if err != nil {
103+
return nil, fmt.Errorf("error fetching IPs from IPAM: %w", err)
104+
}
105+
106+
if len(resp.IPs) == 0 {
107+
return nil, nil
108+
}
109+
110+
ipList := make([]map[string]interface{}, 0, len(resp.IPs))
111+
for _, ip := range resp.IPs {
112+
ipNet := ip.Address
113+
if ipNet.IP == nil {
114+
continue
115+
}
116+
ipMap := map[string]interface{}{
117+
"id": regional.NewIDString(region, ip.ID),
118+
"address": ipNet.IP.String(),
119+
}
120+
ipList = append(ipList, ipMap)
121+
}
122+
123+
return ipList, nil
124+
}

0 commit comments

Comments
 (0)