Skip to content

Commit d404ec0

Browse files
authored
feat(ipam): add ips datasource (#2354)
* feat(ipam): add ips datasource * lint * fix
1 parent d1af9ac commit d404ec0

File tree

6 files changed

+4271
-0
lines changed

6 files changed

+4271
-0
lines changed

docs/data-sources/ipam_ips.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
subcategory: "IPAM"
3+
page_title: "Scaleway: scaleway_ipam_ips"
4+
---
5+
6+
# scaleway_ipam_ips
7+
8+
Gets information about multiple IPs managed by IPAM service.
9+
10+
## Examples
11+
12+
### By tag
13+
14+
```terraform
15+
data "scaleway_ipam_ips" "by_tag" {
16+
tags = ["tag"]
17+
}
18+
```
19+
20+
### By type and resource
21+
22+
```terraform
23+
resource "scaleway_vpc" "vpc01" {
24+
name = "my vpc"
25+
}
26+
27+
resource "scaleway_vpc_private_network" "pn01" {
28+
vpc_id = scaleway_vpc.vpc01.id
29+
ipv4_subnet {
30+
subnet = "172.16.32.0/22"
31+
}
32+
}
33+
34+
resource "scaleway_redis_cluster" "redis01" {
35+
name = "my_redis_cluster"
36+
version = "7.0.5"
37+
node_type = "RED1-XS"
38+
user_name = "my_initial_user"
39+
password = "thiZ_is_v&ry_s3cret"
40+
cluster_size = 3
41+
private_network {
42+
id = scaleway_vpc_private_network.pn01.id
43+
}
44+
}
45+
46+
data "scaleway_ipam_ips" "by_type_and_resource" {
47+
type = "ipv4"
48+
resource {
49+
id = scaleway_redis_cluster.redis01.id
50+
type = "redis_cluster"
51+
}
52+
}
53+
```
54+
55+
## Argument Reference
56+
57+
- `type` - (Optional) The type of IP used as filter (ipv4, ipv6).
58+
59+
- `private_network_id` - (Optional) The ID of the private network used as filter.
60+
61+
- `resource` - (Optional) Filter by resource ID, type or name.
62+
- `id` - The ID of the resource that the IP is bound to.
63+
- `type` - The type of the resource to get the IP from. [Documentation](https://pkg.go.dev/github.com/scaleway/scaleway-sdk-go@master/api/ipam/v1#pkg-constants) with type list.
64+
- `name` - The name of the resource to get the IP from.
65+
66+
- `mac_address` - (Optional) The Mac Address used as filter.
67+
68+
- `tags` (Optional) The tags used as filter.
69+
70+
- `attached` - (Optional) Defines whether to filter only for IPs which are attached to a resource.
71+
72+
- `zonal` - (Optional) Only IPs that are zonal, and in this zone, will be returned.
73+
74+
- `region` - (Optional) The region used as filter.
75+
76+
- `project_id` - (Optional) The ID of the project used as filter.
77+
78+
- `organization_id` - (Optional) The ID of the organization used as filter.
79+
80+
## Attributes Reference
81+
82+
In addition to all above arguments, the following attributes are exported:
83+
84+
- `id` - The region of the IPS
85+
- `ips` - List of found IPs
86+
- `id` - The ID of the IP.
87+
88+
~> **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`
89+
90+
- `address` - The Scaleway internal IP address of the server.
91+
- `resource` - The list of public IPs of the server.
92+
- `id` - The ID of the resource.
93+
- `type` - The type of resource.
94+
- `mac_address` - The mac address.
95+
- `name` - The name of the resource.
96+
- `tags` - The tags associated with the IP.
97+
- `created_at` - The date and time of the creation of the IP.
98+
- `updated_at` - The date and time of the last update of the IP.
99+
- `zone` - The [zone](../guides/regions_and_zones.md#zones) in which the IP is.
100+
- `region` - The [region](../guides/regions_and_zones.md#regions) in which the IP is.
101+
- `project_id` - The ID of the project the server is associated with.
102+

scaleway/data_source_ipam_ips.go

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
package scaleway
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/go-cty/cty"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
)
12+
13+
func dataSourceScalewayIPAMIPs() *schema.Resource {
14+
return &schema.Resource{
15+
ReadContext: dataSourceScalewayIPAMIPsRead,
16+
Schema: map[string]*schema.Schema{
17+
"private_network_id": {
18+
Type: schema.TypeString,
19+
Optional: true,
20+
Description: "The private Network to filter for",
21+
},
22+
"attached": {
23+
Type: schema.TypeBool,
24+
Optional: true,
25+
Description: "Defines whether to filter only for IPs which are attached to a resource",
26+
},
27+
"tags": {
28+
Type: schema.TypeList,
29+
Optional: true,
30+
Description: "The tags associated with the IP to filter for",
31+
Elem: &schema.Schema{
32+
Type: schema.TypeString,
33+
},
34+
},
35+
"resource": {
36+
Type: schema.TypeList,
37+
Optional: true,
38+
MaxItems: 1,
39+
Description: "The IP resource to filter for",
40+
Elem: &schema.Resource{
41+
Schema: map[string]*schema.Schema{
42+
"id": {
43+
Type: schema.TypeString,
44+
Optional: true,
45+
Description: "ID of the resource to filter for",
46+
},
47+
"type": {
48+
Type: schema.TypeString,
49+
Required: true,
50+
Description: "Type of resource to filter for",
51+
},
52+
"name": {
53+
Type: schema.TypeString,
54+
Optional: true,
55+
Description: "Name of the resource to filter for",
56+
},
57+
},
58+
},
59+
},
60+
"mac_address": {
61+
Type: schema.TypeString,
62+
Optional: true,
63+
Description: "The MAC address to filter for",
64+
},
65+
"type": {
66+
Type: schema.TypeString,
67+
Optional: true,
68+
Description: "IP Type (ipv4, ipv6) to filter for",
69+
},
70+
"zonal": zoneSchema(),
71+
"region": regionSchema(),
72+
"project_id": projectIDSchema(),
73+
"organization_id": organizationIDSchema(),
74+
// Computed
75+
"ips": {
76+
Type: schema.TypeList,
77+
Computed: true,
78+
Elem: &schema.Resource{
79+
Schema: map[string]*schema.Schema{
80+
"id": {
81+
Computed: true,
82+
Type: schema.TypeString,
83+
},
84+
"address": {
85+
Computed: true,
86+
Type: schema.TypeString,
87+
},
88+
"resource": {
89+
Type: schema.TypeList,
90+
Computed: true,
91+
Elem: &schema.Resource{
92+
Schema: map[string]*schema.Schema{
93+
"type": {
94+
Type: schema.TypeString,
95+
Computed: true,
96+
},
97+
"id": {
98+
Type: schema.TypeString,
99+
Computed: true,
100+
},
101+
"mac_address": {
102+
Type: schema.TypeString,
103+
Computed: true,
104+
},
105+
"name": {
106+
Type: schema.TypeString,
107+
Computed: true,
108+
},
109+
},
110+
},
111+
},
112+
"tags": {
113+
Type: schema.TypeList,
114+
Computed: true,
115+
Elem: &schema.Schema{
116+
Type: schema.TypeString,
117+
},
118+
},
119+
"created_at": {
120+
Computed: true,
121+
Type: schema.TypeString,
122+
},
123+
"updated_at": {
124+
Computed: true,
125+
Type: schema.TypeString,
126+
},
127+
"region": regionComputedSchema(),
128+
"zone": zoneComputedSchema(),
129+
"project_id": projectIDSchema(),
130+
},
131+
},
132+
},
133+
},
134+
}
135+
}
136+
137+
func dataSourceScalewayIPAMIPsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
138+
api, region, err := ipamAPIWithRegion(d, meta)
139+
if err != nil {
140+
return diag.FromErr(err)
141+
}
142+
143+
req := &ipam.ListIPsRequest{
144+
Region: region,
145+
ProjectID: expandStringPtr(d.Get("project_id")),
146+
Zonal: expandStringPtr(d.Get("zonal")),
147+
PrivateNetworkID: expandStringPtr(d.Get("private_network_id")),
148+
ResourceID: expandStringPtr(expandLastID(d.Get("resource.0.id"))),
149+
ResourceType: ipam.ResourceType(d.Get("resource.0.type").(string)),
150+
ResourceName: expandStringPtr(d.Get("resource.0.name")),
151+
MacAddress: expandStringPtr(d.Get("mac_address")),
152+
Tags: expandStrings(d.Get("tags")),
153+
OrganizationID: expandStringPtr(d.Get("organization_id")),
154+
}
155+
156+
attached, attachedExists := d.GetOk("attached")
157+
if attachedExists {
158+
req.Attached = expandBoolPtr(attached)
159+
}
160+
161+
ipType, ipTypeExist := d.GetOk("type")
162+
if ipTypeExist {
163+
switch ipType.(string) {
164+
case "ipv4":
165+
req.IsIPv6 = scw.BoolPtr(false)
166+
case "ipv6":
167+
req.IsIPv6 = scw.BoolPtr(true)
168+
default:
169+
return diag.Diagnostics{{
170+
Severity: diag.Error,
171+
Summary: "Invalid IP Type",
172+
Detail: "Expected ipv4 or ipv6",
173+
AttributePath: cty.GetAttrPath("type"),
174+
}}
175+
}
176+
}
177+
178+
resp, err := api.ListIPs(req, scw.WithAllPages(), scw.WithContext(ctx))
179+
if err != nil {
180+
return diag.FromErr(err)
181+
}
182+
183+
ips := []interface{}(nil)
184+
for _, ip := range resp.IPs {
185+
address, err := flattenIPNet(ip.Address)
186+
if err != nil {
187+
return diag.FromErr(err)
188+
}
189+
190+
rawIP := make(map[string]interface{})
191+
rawIP["id"] = newRegionalIDString(region, ip.ID)
192+
rawIP["address"] = address
193+
rawIP["resource"] = flattenIPResource(ip.Resource)
194+
rawIP["tags"] = ip.Tags
195+
rawIP["created_at"] = flattenTime(ip.CreatedAt)
196+
rawIP["updated_at"] = flattenTime(ip.UpdatedAt)
197+
rawIP["region"] = ip.Region.String()
198+
rawIP["project_id"] = ip.ProjectID
199+
200+
if ip.Zone != nil {
201+
rawIP["zone"] = ip.Zone.String()
202+
}
203+
204+
ips = append(ips, rawIP)
205+
}
206+
207+
d.SetId(region.String())
208+
_ = d.Set("ips", ips)
209+
210+
return nil
211+
}

0 commit comments

Comments
 (0)