Skip to content

feat(ipam): add ips datasource #2354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions docs/data-sources/ipam_ips.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
subcategory: "IPAM"
page_title: "Scaleway: scaleway_ipam_ips"
---

# scaleway_ipam_ips

Gets information about multiple IPs managed by IPAM service.

## Examples

### By tag

```terraform
data "scaleway_ipam_ips" "by_tag" {
tags = ["tag"]
}
```

### By type and resource

```terraform
resource "scaleway_vpc" "vpc01" {
name = "my vpc"
}

resource "scaleway_vpc_private_network" "pn01" {
vpc_id = scaleway_vpc.vpc01.id
ipv4_subnet {
subnet = "172.16.32.0/22"
}
}

resource "scaleway_redis_cluster" "redis01" {
name = "my_redis_cluster"
version = "7.0.5"
node_type = "RED1-XS"
user_name = "my_initial_user"
password = "thiZ_is_v&ry_s3cret"
cluster_size = 3
private_network {
id = scaleway_vpc_private_network.pn01.id
}
}

data "scaleway_ipam_ips" "by_type_and_resource" {
type = "ipv4"
resource {
id = scaleway_redis_cluster.redis01.id
type = "redis_cluster"
}
}
```

## Argument Reference

- `type` - (Optional) The type of IP used as filter (ipv4, ipv6).

- `private_network_id` - (Optional) The ID of the private network used as filter.

- `resource` - (Optional) Filter by resource ID, type or name.
- `id` - The ID of the resource that the IP is bound to.
- `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.
- `name` - The name of the resource to get the IP from.

- `mac_address` - (Optional) The Mac Address used as filter.

- `tags` (Optional) The tags used as filter.

- `attached` - (Optional) Defines whether to filter only for IPs which are attached to a resource.

- `zonal` - (Optional) Only IPs that are zonal, and in this zone, will be returned.

- `region` - (Optional) The region used as filter.

- `project_id` - (Optional) The ID of the project used as filter.

- `organization_id` - (Optional) The ID of the organization used as filter.

## Attributes Reference

In addition to all above arguments, the following attributes are exported:

- `id` - The region of the IPS
- `ips` - List of found IPs
- `id` - The ID of the IP.

~> **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`

- `address` - The Scaleway internal IP address of the server.
- `resource` - The list of public IPs of the server.
- `id` - The ID of the resource.
- `type` - The type of resource.
- `mac_address` - The mac address.
- `name` - The name of the resource.
- `tags` - The tags associated with the IP.
- `created_at` - The date and time of the creation of the IP.
- `updated_at` - The date and time of the last update of the IP.
- `zone` - The [zone](../guides/regions_and_zones.md#zones) in which the IP is.
- `region` - The [region](../guides/regions_and_zones.md#regions) in which the IP is.
- `project_id` - The ID of the project the server is associated with.

211 changes: 211 additions & 0 deletions scaleway/data_source_ipam_ips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package scaleway

import (
"context"

"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func dataSourceScalewayIPAMIPs() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceScalewayIPAMIPsRead,
Schema: map[string]*schema.Schema{
"private_network_id": {
Type: schema.TypeString,
Optional: true,
Description: "The private Network to filter for",
},
"attached": {
Type: schema.TypeBool,
Optional: true,
Description: "Defines whether to filter only for IPs which are attached to a resource",
},
"tags": {
Type: schema.TypeList,
Optional: true,
Description: "The tags associated with the IP to filter for",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"resource": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "The IP resource to filter for",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Optional: true,
Description: "ID of the resource to filter for",
},
"type": {
Type: schema.TypeString,
Required: true,
Description: "Type of resource to filter for",
},
"name": {
Type: schema.TypeString,
Optional: true,
Description: "Name of the resource to filter for",
},
},
},
},
"mac_address": {
Type: schema.TypeString,
Optional: true,
Description: "The MAC address to filter for",
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: "IP Type (ipv4, ipv6) to filter for",
},
"zonal": zoneSchema(),
"region": regionSchema(),
"project_id": projectIDSchema(),
"organization_id": organizationIDSchema(),
// Computed
"ips": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Computed: true,
Type: schema.TypeString,
},
"address": {
Computed: true,
Type: schema.TypeString,
},
"resource": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeString,
Computed: true,
},
"mac_address": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"tags": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"created_at": {
Computed: true,
Type: schema.TypeString,
},
"updated_at": {
Computed: true,
Type: schema.TypeString,
},
"region": regionComputedSchema(),
"zone": zoneComputedSchema(),
"project_id": projectIDSchema(),
},
},
},
},
}
}

func dataSourceScalewayIPAMIPsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
api, region, err := ipamAPIWithRegion(d, meta)
if err != nil {
return diag.FromErr(err)
}

req := &ipam.ListIPsRequest{
Region: region,
ProjectID: expandStringPtr(d.Get("project_id")),
Zonal: expandStringPtr(d.Get("zonal")),
PrivateNetworkID: expandStringPtr(d.Get("private_network_id")),
ResourceID: expandStringPtr(expandLastID(d.Get("resource.0.id"))),
ResourceType: ipam.ResourceType(d.Get("resource.0.type").(string)),
ResourceName: expandStringPtr(d.Get("resource.0.name")),
MacAddress: expandStringPtr(d.Get("mac_address")),
Tags: expandStrings(d.Get("tags")),
OrganizationID: expandStringPtr(d.Get("organization_id")),
}

attached, attachedExists := d.GetOk("attached")
if attachedExists {
req.Attached = expandBoolPtr(attached)
}

ipType, ipTypeExist := d.GetOk("type")
if ipTypeExist {
switch ipType.(string) {
case "ipv4":
req.IsIPv6 = scw.BoolPtr(false)
case "ipv6":
req.IsIPv6 = scw.BoolPtr(true)
default:
return diag.Diagnostics{{
Severity: diag.Error,
Summary: "Invalid IP Type",
Detail: "Expected ipv4 or ipv6",
AttributePath: cty.GetAttrPath("type"),
}}
}
}

resp, err := api.ListIPs(req, scw.WithAllPages(), scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

ips := []interface{}(nil)
for _, ip := range resp.IPs {
address, err := flattenIPNet(ip.Address)
if err != nil {
return diag.FromErr(err)
}

rawIP := make(map[string]interface{})
rawIP["id"] = newRegionalIDString(region, ip.ID)
rawIP["address"] = address
rawIP["resource"] = flattenIPResource(ip.Resource)
rawIP["tags"] = ip.Tags
rawIP["created_at"] = flattenTime(ip.CreatedAt)
rawIP["updated_at"] = flattenTime(ip.UpdatedAt)
rawIP["region"] = ip.Region.String()
rawIP["project_id"] = ip.ProjectID

if ip.Zone != nil {
rawIP["zone"] = ip.Zone.String()
}

ips = append(ips, rawIP)
}

d.SetId(region.String())
_ = d.Set("ips", ips)

return nil
}
Loading