Skip to content
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

feat(instance): add instance_servers data source #1264

Merged
merged 15 commits into from
Jun 7, 2022
Merged
64 changes: 64 additions & 0 deletions docs/data-sources/instance_servers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
page_title: "Scaleway: scaleway_instance_servers"
description: |-
Gets information about multiple Instance Servers.
---

# scaleway_instance_servers

Gets information about multiple instance servers.

## Examples

### Basic

```hcl
# Find servers by tag
data "scaleway_instance_servers" "my_key" {
tags = ["tag"]
}

# Find servers by name and zone
data "scaleway_instance_servers" "my_key" {
name = "myserver"
zone = "fr-par-2"
}
```

## Argument Reference

- `name` - (Optional) The server name used as filter. Servers with a name like it are listed.

- `tags` - (Optional) List of tags used as filter. Servers with these exact tags are listed.

- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which servers exist.

## Attributes Reference

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

- `id` - The zone of the servers

- `servers` - List of found servers
- `id` - The ID of the server.
- `tags` - The tags associated with the server.
- `public_ip` - The public IPv4 address of the server.
- `private_ip` - The Scaleway internal IP address of the server.
- `state` - The state of the server. Possible values are: `started`, `stopped` or `standby`.
- `zone` - The [zone](../guides/regions_and_zones.md#zones) in which the server is.
- `name` - The name of the server.
- `boot_type` - The boot Type of the server. Possible values are: `local`, `bootscript` or `rescue`.
- `bootscript_id` - The ID of the bootscript.
- `type` - The commercial type of the server.
- `security_group_id` - The [security group](https://developers.scaleway.com/en/products/instance/api/#security-groups-8d7f89) the server is attached to.
- `enable_ipv6` - Determines if IPv6 is enabled for the server.
- `ipv6_address` - The default ipv6 address routed to the server. ( Only set when enable_ipv6 is set to true )
- `ipv6_gateway` - The ipv6 gateway address. ( Only set when enable_ipv6 is set to true )
- `ipv6_prefix_length` - The prefix length of the ipv6 subnet routed to the server. ( Only set when enable_ipv6 is set to true )
- `enable_dynamic_ip` - If true a dynamic IP will be attached to the server.
- `image` - The UUID or the label of the base image used by the server.
- `placement_group_id` - The [placement group](https://developers.scaleway.com/en/products/instance/api/#placement-groups-d8f653) the server is attached to.
- `organization_id` - The organization ID the server is associated with.
- `project_id` - The ID of the project the server is associated with.


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

import (
"context"
"fmt"
"strconv"

"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"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func dataSourceScalewayInstanceServers() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceScalewayInstanceServersRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Description: "Servers with a name like it are listed.",
},
"tags": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "Servers with these exact tags are listed.",
},
"servers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Computed: true,
Type: schema.TypeString,
},
"public_ip": {
Computed: true,
Type: schema.TypeString,
},
"private_ip": {
Computed: true,
Type: schema.TypeString,
},
"state": {
Computed: true,
Type: schema.TypeString,
},
"name": {
Computed: true,
Type: schema.TypeString,
},
"boot_type": {
Computed: true,
Type: schema.TypeString,
},
"bootscript_id": {
Computed: true,
Type: schema.TypeString,
},
"type": {
Computed: true,
Type: schema.TypeString,
},
"tags": {
Computed: true,
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"security_group_id": {
Computed: true,
Type: schema.TypeString,
},
"enable_ipv6": {
Computed: true,
Type: schema.TypeBool,
},
"enable_dynamic_ip": {
Computed: true,
Type: schema.TypeBool,
},
"image": {
Computed: true,
Type: schema.TypeString,
},
"placement_group_id": {
Computed: true,
Type: schema.TypeString,
},
"placement_group_policy_respected": {
Computed: true,
Type: schema.TypeBool,
},
"ipv6_address": {
Computed: true,
Type: schema.TypeString,
},
"ipv6_gateway": {
Computed: true,
Type: schema.TypeString,
},
"ipv6_prefix_length": {
Computed: true,
Type: schema.TypeInt,
},
"zone": zoneSchema(),
"organization_id": organizationIDSchema(),
"project_id": projectIDSchema(),
},
},
},
"zone": zoneSchema(),
"organization_id": organizationIDSchema(),
"project_id": projectIDSchema(),
},
}
}

func dataSourceScalewayInstanceServersRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
instanceAPI, zone, err := instanceAPIWithZone(d, meta)
if err != nil {
return diag.FromErr(err)
}
res, err := instanceAPI.ListServers(&instance.ListServersRequest{
Zone: zone,
Name: expandStringPtr(d.Get("name")),
Project: expandStringPtr(d.Get("project_id")),
Tags: expandStrings(d.Get("tags")),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

var diags diag.Diagnostics

servers := []interface{}(nil)
for _, server := range res.Servers {
rawServer := make(map[string]interface{})
rawServer["id"] = newZonedID(server.Zone, server.ID).String()
if server.PublicIP != nil {
rawServer["public_ip"] = server.PublicIP.Address.String()
}
if server.PrivateIP != nil {
rawServer["private_ip"] = *server.PrivateIP
}
state, err := serverStateFlatten(server.State)
if err != nil {
diags = append(diags, diag.FromErr(err)...)
continue
}
rawServer["state"] = state
rawServer["zone"] = string(zone)
rawServer["name"] = server.Name
rawServer["boot_type"] = server.BootType
rawServer["bootscript_id"] = server.Bootscript.ID
rawServer["type"] = server.CommercialType
if len(server.Tags) > 0 {
rawServer["tags"] = server.Tags
}
rawServer["security_group_id"] = newZonedID(zone, server.SecurityGroup.ID).String()
rawServer["enable_ipv6"] = server.EnableIPv6
rawServer["enable_dynamic_ip"] = server.DynamicIPRequired
rawServer["organization_id"] = server.Organization
rawServer["project_id"] = server.Project
if server.Image != nil {
rawServer["image"] = server.Image.ID
}
if server.PlacementGroup != nil {
rawServer["placement_group_id"] = newZonedID(zone, server.PlacementGroup.ID).String()
rawServer["placement_group_policy_respected"] = server.PlacementGroup.PolicyRespected
}
if server.IPv6 != nil {
rawServer["ipv6_address"] = server.IPv6.Address.String()
rawServer["ipv6_gateway"] = server.IPv6.Gateway.String()
prefixLength, err := strconv.Atoi(server.IPv6.Netmask)
if err != nil {
diags = append(diags, diag.FromErr(fmt.Errorf("failed to read ipv6 netmask: %w", err))...)
continue
} else {
rawServer["ipv6_prefix_length"] = prefixLength
}
}

servers = append(servers, rawServer)
}
if len(diags) > 0 {
return diags
}

d.SetId(zone.String())
_ = d.Set("servers", servers)

return nil
}
88 changes: 88 additions & 0 deletions scaleway/data_source_instance_servers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package scaleway

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccScalewayDataSourceInstanceServers_Basic(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayInstanceServerDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_instance_server" "server1" {
name = "tf-server-datasource0"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
}`,
},
{
Config: `
resource "scaleway_instance_server" "server1" {
name = "tf-server-datasource0"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
}

resource "scaleway_instance_server" "server2" {
name = "tf-server-datasource1"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
}`,
},
{
Config: `
resource "scaleway_instance_server" "server1" {
name = "tf-server-datasource0"
image = "ubuntu_focal"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
}

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

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

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"
zone = "fr-par-2"
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.0.id"),
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.1.id"),

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

resource.TestCheckNoResourceAttr("data.scaleway_instance_servers.servers_by_name_other_zone", "servers.0.id"),
),
},
},
})
}
1 change: 1 addition & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
"scaleway_instance_ip": dataSourceScalewayInstanceIP(),
"scaleway_instance_security_group": dataSourceScalewayInstanceSecurityGroup(),
"scaleway_instance_server": dataSourceScalewayInstanceServer(),
"scaleway_instance_servers": dataSourceScalewayInstanceServers(),
"scaleway_instance_image": dataSourceScalewayInstanceImage(),
"scaleway_instance_volume": dataSourceScalewayInstanceVolume(),
"scaleway_iot_hub": dataSourceScalewayIotHub(),
Expand Down
Loading