Skip to content

Commit b85f46a

Browse files
committed
feat(k8s): read pool's private ips
1 parent 8801985 commit b85f46a

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed

docs/resources/k8s_pool.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ In addition to all arguments above, the following attributes are exported:
114114
- `updated_at` - The last update date of the pool.
115115
- `version` - The version of the pool.
116116
- `current_size` - The size of the pool at the time the terraform state was updated.
117+
- `private_ips` - The list of private IPv4 addresses associated with the resource.
118+
- `id` - The ID of the IPv4 address resource.
119+
- `address` - The private IPv4 address.
117120

118121
## Zone
119122

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/k8s/helpers_k8s.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ func convertNodes(res *k8s.ListNodesResponse) []map[string]interface{} {
8686

8787
for _, node := range res.Nodes {
8888
n := make(map[string]interface{})
89+
n["id"] = node.ID
8990
n["name"] = node.Name
9091
n["status"] = node.Status.String()
9192

internal/services/k8s/pool.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1414
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
1515
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
16+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
1617
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
1718
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
1819
)
@@ -192,6 +193,11 @@ func ResourcePool() *schema.Resource {
192193
Computed: true,
193194
Elem: &schema.Resource{
194195
Schema: map[string]*schema.Schema{
196+
"id": {
197+
Type: schema.TypeString,
198+
Computed: true,
199+
Description: "The ID of the node",
200+
},
195201
"name": {
196202
Type: schema.TypeString,
197203
Computed: true,
@@ -222,6 +228,25 @@ func ResourcePool() *schema.Resource {
222228
Computed: true,
223229
Description: "The status of the pool",
224230
},
231+
"private_ips": {
232+
Type: schema.TypeList,
233+
Computed: true,
234+
Description: "List of private IPv4 addresses associated with the resource",
235+
Elem: &schema.Resource{
236+
Schema: map[string]*schema.Schema{
237+
"id": {
238+
Type: schema.TypeString,
239+
Computed: true,
240+
Description: "The ID of the IPv4 address resource",
241+
},
242+
"address": {
243+
Type: schema.TypeString,
244+
Computed: true,
245+
Description: "The private IPv4 address",
246+
},
247+
},
248+
},
249+
},
225250
},
226251
}
227252
}
@@ -401,6 +426,35 @@ func ResourceK8SPoolRead(ctx context.Context, d *schema.ResourceData, m interfac
401426
_ = d.Set("placement_group_id", zonal.NewID(pool.Zone, *pool.PlacementGroupID).String())
402427
}
403428

429+
var allPrivateIPs []map[string]interface{}
430+
431+
for _, nodeMap := range nodes {
432+
nodeNameInterface, ok := nodeMap["name"]
433+
if !ok {
434+
continue
435+
}
436+
437+
nodeName, ok := nodeNameInterface.(string)
438+
if !ok {
439+
continue
440+
}
441+
442+
opts := &ipam.GetResourcePrivateIPsOptions{
443+
ResourceName: &nodeName,
444+
}
445+
446+
privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)
447+
if err != nil {
448+
return diag.FromErr(err)
449+
}
450+
451+
if privateIPs != nil {
452+
allPrivateIPs = append(allPrivateIPs, privateIPs...)
453+
}
454+
}
455+
456+
_ = d.Set("private_ips", allPrivateIPs)
457+
404458
return nil
405459
}
406460

internal/services/k8s/pool_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ func TestAccPool_Basic(t *testing.T) {
5050
resource.TestCheckResourceAttr("scaleway_k8s_pool.default", "tags.1", "scaleway_k8s_cluster"),
5151
resource.TestCheckResourceAttr("scaleway_k8s_pool.default", "tags.2", "default"),
5252
testAccCheckK8SPoolServersAreInPrivateNetwork(tt, "scaleway_k8s_cluster.minimal", "scaleway_k8s_pool.default", "scaleway_vpc_private_network.minimal"),
53+
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.default", "private_ips.0.id"),
54+
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.default", "private_ips.0.address"),
5355
),
5456
},
5557
{
@@ -69,6 +71,10 @@ func TestAccPool_Basic(t *testing.T) {
6971
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.minimal", "nodes.0.public_ip"), // Deprecated attributes
7072
testAccCheckK8SPoolServersAreInPrivateNetwork(tt, "scaleway_k8s_cluster.minimal", "scaleway_k8s_pool.default", "scaleway_vpc_private_network.minimal"),
7173
testAccCheckK8SPoolServersAreInPrivateNetwork(tt, "scaleway_k8s_cluster.minimal", "scaleway_k8s_pool.minimal", "scaleway_vpc_private_network.minimal"),
74+
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.default", "private_ips.0.id"),
75+
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.default", "private_ips.0.address"),
76+
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.default", "private_ips.1.id"),
77+
resource.TestCheckResourceAttrSet("scaleway_k8s_pool.default", "private_ips.1.address"),
7278
),
7379
},
7480
{

0 commit comments

Comments
 (0)