Skip to content
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
3 changes: 3 additions & 0 deletions docs/data-sources/instance_servers.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ In addition to all above arguments, the following attributes are exported:
- `tags` - The tags associated with the server.
- `public_ip` - The public IP address of the server.
- `private_ip` - The Scaleway internal IP address of the server.
- `private_ips` - The list of private IPv4 and IPv6 addresses associated with the server.
- `id` - The ID of the IP address resource.
- `address` - The private IP address.
- `public_ips` - The list of public IPs of the server
- `id` - The ID of the IP
- `address` - The address of the IP
Expand Down
80 changes: 80 additions & 0 deletions internal/services/instance/servers_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import (
"fmt"
"strconv"

"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/instance/v1"
ipamAPI "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/ipam"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
)

Expand Down Expand Up @@ -65,6 +69,26 @@ func DataSourceServers() *schema.Resource {
Computed: true,
Type: schema.TypeString,
},
"private_ips": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: "List of private IPv4 and IPv6 addresses associated with the resource",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the IPv4/v6 address resource",
},
"address": {
Type: schema.TypeString,
Computed: true,
Description: "The private IPv4/v6 address",
},
},
},
},
"state": {
Computed: true,
Type: schema.TypeString,
Expand Down Expand Up @@ -227,6 +251,62 @@ func DataSourceInstanceServersRead(ctx context.Context, d *schema.ResourceData,
rawServer["ipv6_prefix_length"] = prefixLength
}

ph, err := newPrivateNICHandler(instanceAPI, server.ID, zone)
if err != nil {
return diag.FromErr(err)
}

privateNICIDs := []string(nil)
for _, nic := range ph.privateNICsMap {
privateNICIDs = append(privateNICIDs, nic.ID)
}

// Read server's private IPs if possible
allPrivateIPs := []map[string]any(nil)
resourceType := ipamAPI.ResourceTypeInstancePrivateNic

region, err := zone.Region()
if err != nil {
return append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: "Unable to get server's private IPs",
Detail: err.Error(),
})
}

for _, nicID := range privateNICIDs {
opts := &ipam.GetResourcePrivateIPsOptions{
ResourceType: &resourceType,
ResourceID: &nicID,
ProjectID: &server.Project,
}

privateIPs, err := ipam.GetResourcePrivateIPs(ctx, m, region, opts)

switch {
case err == nil:
allPrivateIPs = append(allPrivateIPs, privateIPs...)
case httperrors.Is403(err):
return append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: "Unauthorized to read server's private IPs, please check your IAM permissions",
Detail: err.Error(),
AttributePath: cty.GetAttrPath("private_ips"),
})
default:
diags = append(diags, diag.Diagnostic{
Severity: diag.Warning,
Summary: fmt.Sprintf("Unable to get private IPs for server %s (pnic_id: %s)", server.ID, nicID),
Detail: err.Error(),
AttributePath: cty.GetAttrPath("private_ips"),
})
}

if len(allPrivateIPs) > 0 {
rawServer["private_ips"] = allPrivateIPs
}
}

servers = append(servers, rawServer)
}

Expand Down
117 changes: 117 additions & 0 deletions internal/services/instance/servers_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,120 @@ func TestAccDataSourceServers_Basic(t *testing.T) {
},
})
}

func TestAccDataSourceServers_PrivateIPs(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: instancechecks.IsServerDestroyed(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_vpc_private_network" "pn01" {
name = "private_network_instance_servers"
}

resource "scaleway_instance_server" "server1" {
name = "tf-server-datasource-private-ips-0"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]

private_network {
pn_id = scaleway_vpc_private_network.pn01.id
}
}`,
},
{
Config: `
resource "scaleway_vpc_private_network" "pn01" {
name = "private_network_instance_servers"
}

resource "scaleway_instance_server" "server1" {
name = "tf-server-datasource-private-ips-0"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]

private_network {
pn_id = scaleway_vpc_private_network.pn01.id
}
}

resource "scaleway_instance_server" "server2" {
name = "tf-server-datasource-private-ips-1"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]

private_network {
pn_id = scaleway_vpc_private_network.pn01.id
}
}`,
},
{
Config: `
resource "scaleway_vpc_private_network" "pn01" {
name = "private_network_instance_servers"
}

resource "scaleway_instance_server" "server1" {
name = "tf-server-datasource-private-ips-0"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]

private_network {
pn_id = scaleway_vpc_private_network.pn01.id
}
}

resource "scaleway_instance_server" "server2" {
name = "tf-server-datasource-private-ips-1"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]

private_network {
pn_id = scaleway_vpc_private_network.pn01.id
}
}

data "scaleway_instance_servers" "servers_by_name" {
name = "tf-server-datasource-private-ips"
}

data "scaleway_instance_servers" "servers_by_tag" {
tags = ["data_scaleway_instance_servers", "terraform-test"]
}

data "scaleway_instance_servers" "servers_by_name_other_zone" {
name = "tf-server-datasource-private-ips"
zone = "fr-par-2"
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.0.private_ips.0.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.0.private_ips.1.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.1.private_ips.0.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.1.private_ips.1.id"),

resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_name", "servers.0.private_ips.0.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_name", "servers.0.private_ips.1.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_name", "servers.1.private_ips.0.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_name", "servers.1.private_ips.1.id"),

resource.TestCheckNoResourceAttr("data.scaleway_instance_servers.servers_by_name_other_zone", "servers.0.id"),
),
},
},
})
}
Loading
Loading