Skip to content

Commit 3f4d176

Browse files
Codelaxremyleone
andcommitted
feat(instance): add instance_servers data source (scaleway#1264)
Co-authored-by: Rémy Léone <[email protected]>
1 parent 70e950b commit 3f4d176

5 files changed

+6581
-0
lines changed

docs/data-sources/instance_servers.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
page_title: "Scaleway: scaleway_instance_servers"
3+
description: |-
4+
Gets information about multiple Instance Servers.
5+
---
6+
7+
# scaleway_instance_servers
8+
9+
Gets information about multiple instance servers.
10+
11+
## Examples
12+
13+
### Basic
14+
15+
```hcl
16+
# Find servers by tag
17+
data "scaleway_instance_servers" "my_key" {
18+
tags = ["tag"]
19+
}
20+
21+
# Find servers by name and zone
22+
data "scaleway_instance_servers" "my_key" {
23+
name = "myserver"
24+
zone = "fr-par-2"
25+
}
26+
```
27+
28+
## Argument Reference
29+
30+
- `name` - (Optional) The server name used as filter. Servers with a name like it are listed.
31+
32+
- `tags` - (Optional) List of tags used as filter. Servers with these exact tags are listed.
33+
34+
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which servers exist.
35+
36+
## Attributes Reference
37+
38+
In addition to all above arguments, the following attributes are exported:
39+
40+
- `id` - The zone of the servers
41+
42+
- `servers` - List of found servers
43+
- `id` - The ID of the server.
44+
- `tags` - The tags associated with the server.
45+
- `public_ip` - The public IPv4 address of the server.
46+
- `private_ip` - The Scaleway internal IP address of the server.
47+
- `state` - The state of the server. Possible values are: `started`, `stopped` or `standby`.
48+
- `zone` - The [zone](../guides/regions_and_zones.md#zones) in which the server is.
49+
- `name` - The name of the server.
50+
- `boot_type` - The boot Type of the server. Possible values are: `local`, `bootscript` or `rescue`.
51+
- `bootscript_id` - The ID of the bootscript.
52+
- `type` - The commercial type of the server.
53+
- `security_group_id` - The [security group](https://developers.scaleway.com/en/products/instance/api/#security-groups-8d7f89) the server is attached to.
54+
- `enable_ipv6` - Determines if IPv6 is enabled for the server.
55+
- `ipv6_address` - The default ipv6 address routed to the server. ( Only set when enable_ipv6 is set to true )
56+
- `ipv6_gateway` - The ipv6 gateway address. ( Only set when enable_ipv6 is set to true )
57+
- `ipv6_prefix_length` - The prefix length of the ipv6 subnet routed to the server. ( Only set when enable_ipv6 is set to true )
58+
- `enable_dynamic_ip` - If true a dynamic IP will be attached to the server.
59+
- `image` - The UUID or the label of the base image used by the server.
60+
- `placement_group_id` - The [placement group](https://developers.scaleway.com/en/products/instance/api/#placement-groups-d8f653) the server is attached to.
61+
- `organization_id` - The organization ID the server is associated with.
62+
- `project_id` - The ID of the project the server is associated with.
63+
64+
+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package scaleway
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strconv"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
)
13+
14+
func dataSourceScalewayInstanceServers() *schema.Resource {
15+
return &schema.Resource{
16+
ReadContext: dataSourceScalewayInstanceServersRead,
17+
Schema: map[string]*schema.Schema{
18+
"name": {
19+
Type: schema.TypeString,
20+
Optional: true,
21+
Description: "Servers with a name like it are listed.",
22+
},
23+
"tags": {
24+
Type: schema.TypeList,
25+
Elem: &schema.Schema{
26+
Type: schema.TypeString,
27+
},
28+
Optional: true,
29+
Description: "Servers with these exact tags are listed.",
30+
},
31+
"servers": {
32+
Type: schema.TypeList,
33+
Computed: true,
34+
Elem: &schema.Resource{
35+
Schema: map[string]*schema.Schema{
36+
"id": {
37+
Computed: true,
38+
Type: schema.TypeString,
39+
},
40+
"public_ip": {
41+
Computed: true,
42+
Type: schema.TypeString,
43+
},
44+
"private_ip": {
45+
Computed: true,
46+
Type: schema.TypeString,
47+
},
48+
"state": {
49+
Computed: true,
50+
Type: schema.TypeString,
51+
},
52+
"name": {
53+
Computed: true,
54+
Type: schema.TypeString,
55+
},
56+
"boot_type": {
57+
Computed: true,
58+
Type: schema.TypeString,
59+
},
60+
"bootscript_id": {
61+
Computed: true,
62+
Type: schema.TypeString,
63+
},
64+
"type": {
65+
Computed: true,
66+
Type: schema.TypeString,
67+
},
68+
"tags": {
69+
Computed: true,
70+
Type: schema.TypeList,
71+
Elem: &schema.Schema{
72+
Type: schema.TypeString,
73+
},
74+
},
75+
"security_group_id": {
76+
Computed: true,
77+
Type: schema.TypeString,
78+
},
79+
"enable_ipv6": {
80+
Computed: true,
81+
Type: schema.TypeBool,
82+
},
83+
"enable_dynamic_ip": {
84+
Computed: true,
85+
Type: schema.TypeBool,
86+
},
87+
"image": {
88+
Computed: true,
89+
Type: schema.TypeString,
90+
},
91+
"placement_group_id": {
92+
Computed: true,
93+
Type: schema.TypeString,
94+
},
95+
"placement_group_policy_respected": {
96+
Computed: true,
97+
Type: schema.TypeBool,
98+
},
99+
"ipv6_address": {
100+
Computed: true,
101+
Type: schema.TypeString,
102+
},
103+
"ipv6_gateway": {
104+
Computed: true,
105+
Type: schema.TypeString,
106+
},
107+
"ipv6_prefix_length": {
108+
Computed: true,
109+
Type: schema.TypeInt,
110+
},
111+
"zone": zoneSchema(),
112+
"organization_id": organizationIDSchema(),
113+
"project_id": projectIDSchema(),
114+
},
115+
},
116+
},
117+
"zone": zoneSchema(),
118+
"organization_id": organizationIDSchema(),
119+
"project_id": projectIDSchema(),
120+
},
121+
}
122+
}
123+
124+
func dataSourceScalewayInstanceServersRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
125+
instanceAPI, zone, err := instanceAPIWithZone(d, meta)
126+
if err != nil {
127+
return diag.FromErr(err)
128+
}
129+
res, err := instanceAPI.ListServers(&instance.ListServersRequest{
130+
Zone: zone,
131+
Name: expandStringPtr(d.Get("name")),
132+
Project: expandStringPtr(d.Get("project_id")),
133+
Tags: expandStrings(d.Get("tags")),
134+
}, scw.WithContext(ctx))
135+
if err != nil {
136+
return diag.FromErr(err)
137+
}
138+
139+
var diags diag.Diagnostics
140+
141+
servers := []interface{}(nil)
142+
for _, server := range res.Servers {
143+
rawServer := make(map[string]interface{})
144+
rawServer["id"] = newZonedID(server.Zone, server.ID).String()
145+
if server.PublicIP != nil {
146+
rawServer["public_ip"] = server.PublicIP.Address.String()
147+
}
148+
if server.PrivateIP != nil {
149+
rawServer["private_ip"] = *server.PrivateIP
150+
}
151+
state, err := serverStateFlatten(server.State)
152+
if err != nil {
153+
diags = append(diags, diag.FromErr(err)...)
154+
continue
155+
}
156+
rawServer["state"] = state
157+
rawServer["zone"] = string(zone)
158+
rawServer["name"] = server.Name
159+
rawServer["boot_type"] = server.BootType
160+
rawServer["bootscript_id"] = server.Bootscript.ID
161+
rawServer["type"] = server.CommercialType
162+
if len(server.Tags) > 0 {
163+
rawServer["tags"] = server.Tags
164+
}
165+
rawServer["security_group_id"] = newZonedID(zone, server.SecurityGroup.ID).String()
166+
rawServer["enable_ipv6"] = server.EnableIPv6
167+
rawServer["enable_dynamic_ip"] = server.DynamicIPRequired
168+
rawServer["organization_id"] = server.Organization
169+
rawServer["project_id"] = server.Project
170+
if server.Image != nil {
171+
rawServer["image"] = server.Image.ID
172+
}
173+
if server.PlacementGroup != nil {
174+
rawServer["placement_group_id"] = newZonedID(zone, server.PlacementGroup.ID).String()
175+
rawServer["placement_group_policy_respected"] = server.PlacementGroup.PolicyRespected
176+
}
177+
if server.IPv6 != nil {
178+
rawServer["ipv6_address"] = server.IPv6.Address.String()
179+
rawServer["ipv6_gateway"] = server.IPv6.Gateway.String()
180+
prefixLength, err := strconv.Atoi(server.IPv6.Netmask)
181+
if err != nil {
182+
diags = append(diags, diag.FromErr(fmt.Errorf("failed to read ipv6 netmask: %w", err))...)
183+
continue
184+
} else {
185+
rawServer["ipv6_prefix_length"] = prefixLength
186+
}
187+
}
188+
189+
servers = append(servers, rawServer)
190+
}
191+
if len(diags) > 0 {
192+
return diags
193+
}
194+
195+
d.SetId(zone.String())
196+
_ = d.Set("servers", servers)
197+
198+
return nil
199+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package scaleway
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
7+
)
8+
9+
func TestAccScalewayDataSourceInstanceServers_Basic(t *testing.T) {
10+
tt := NewTestTools(t)
11+
defer tt.Cleanup()
12+
resource.ParallelTest(t, resource.TestCase{
13+
PreCheck: func() { testAccPreCheck(t) },
14+
ProviderFactories: tt.ProviderFactories,
15+
CheckDestroy: testAccCheckScalewayInstanceServerDestroy(tt),
16+
Steps: []resource.TestStep{
17+
{
18+
Config: `
19+
resource "scaleway_instance_server" "server1" {
20+
name = "tf-server-datasource0"
21+
image = "ubuntu_focal"
22+
type = "DEV1-S"
23+
state = "stopped"
24+
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
25+
}`,
26+
},
27+
{
28+
Config: `
29+
resource "scaleway_instance_server" "server1" {
30+
name = "tf-server-datasource0"
31+
image = "ubuntu_focal"
32+
type = "DEV1-S"
33+
state = "stopped"
34+
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
35+
}
36+
37+
resource "scaleway_instance_server" "server2" {
38+
name = "tf-server-datasource1"
39+
image = "ubuntu_focal"
40+
type = "DEV1-S"
41+
state = "stopped"
42+
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
43+
}`,
44+
},
45+
{
46+
Config: `
47+
resource "scaleway_instance_server" "server1" {
48+
name = "tf-server-datasource0"
49+
image = "ubuntu_focal"
50+
type = "DEV1-S"
51+
state = "stopped"
52+
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
53+
}
54+
55+
resource "scaleway_instance_server" "server2" {
56+
name = "tf-server-datasource1"
57+
image = "ubuntu_focal"
58+
type = "DEV1-S"
59+
state = "stopped"
60+
tags = [ "terraform-test", "data_scaleway_instance_servers", "basic" ]
61+
}
62+
63+
data "scaleway_instance_servers" "servers_by_name" {
64+
name = "tf-server-datasource"
65+
}
66+
67+
data "scaleway_instance_servers" "servers_by_tag" {
68+
tags = ["data_scaleway_instance_servers", "terraform-test"]
69+
}
70+
71+
data "scaleway_instance_servers" "servers_by_name_other_zone" {
72+
name = "tf-server-datasource"
73+
zone = "fr-par-2"
74+
}
75+
`,
76+
Check: resource.ComposeTestCheckFunc(
77+
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.0.id"),
78+
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_tag", "servers.1.id"),
79+
80+
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_name", "servers.0.id"),
81+
resource.TestCheckResourceAttrSet("data.scaleway_instance_servers.servers_by_name", "servers.1.id"),
82+
83+
resource.TestCheckNoResourceAttr("data.scaleway_instance_servers.servers_by_name_other_zone", "servers.0.id"),
84+
),
85+
},
86+
},
87+
})
88+
}

scaleway/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
121121
"scaleway_instance_ip": dataSourceScalewayInstanceIP(),
122122
"scaleway_instance_security_group": dataSourceScalewayInstanceSecurityGroup(),
123123
"scaleway_instance_server": dataSourceScalewayInstanceServer(),
124+
"scaleway_instance_servers": dataSourceScalewayInstanceServers(),
124125
"scaleway_instance_image": dataSourceScalewayInstanceImage(),
125126
"scaleway_instance_volume": dataSourceScalewayInstanceVolume(),
126127
"scaleway_iot_hub": dataSourceScalewayIotHub(),

0 commit comments

Comments
 (0)