Skip to content

Commit 4ba763a

Browse files
committed
feat(instance): new data source instance_server_type
1 parent 27a6b65 commit 4ba763a

File tree

7 files changed

+8883
-0
lines changed

7 files changed

+8883
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
subcategory: "Instances"
3+
page_title: "Scaleway: scaleway_instance_server_type"
4+
---
5+
6+
# scaleway_instance_server_type
7+
8+
Gets information about a server type.
9+
10+
## Example Usage
11+
12+
```hcl
13+
data "scaleway_instance_server_type" "pro2-s" {
14+
name = "PRO2-S"
15+
zone = "nl-ams-1"
16+
}
17+
```
18+
19+
## Argument Reference
20+
21+
To select the server type which information should be fetched, the following arguments can be used:
22+
23+
- `name` - (Required) The name of the server type.
24+
Only one of `name` and `snapshot_id` should be specified.
25+
26+
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) of the server type (to check the availability of the server type for example).
27+
28+
## Attributes Reference
29+
30+
The following attributes will be available:
31+
32+
- `arch` - The architecture of the server type.
33+
34+
- `cpu` - The number of CPU cores of the server type.
35+
36+
- `ram` - The amount of RAM of the server type (in bytes).
37+
38+
- `gpu` - The number of GPUs of the server type.
39+
40+
- `volumes` - The specifications of volumes allowed for the server type.
41+
42+
-> The `volumes` block contains:
43+
- `min_size_total` - The minimum total size in bytes of volumes allowed on the server type.
44+
- `max_size_total` - The maximum total size in bytes of volumes allowed on the server type.
45+
- `min_size_per_local_volume` - The minimum size in bytes per local volume allowed on the server type.
46+
- `max_size_per_local_volume` - The maximum size in bytes per local volume allowed on the server type.
47+
- `scratch_storage_max_size` - The maximum size in bytes of the scratch volume allowed on the server type.
48+
- `block_storage` - Whether block storage is allowed on the server type.
49+
50+
- `capabilities` - The specific capabilities of the server type.
51+
52+
-> The `capabilities` block contains:
53+
- `boot_types` - The boot types allowed for the server type.
54+
- `max_file_systems` - The maximum number of file systems that can be attached on the server type.
55+
56+
- `network` - The network specifications of the server type.
57+
58+
-> The `network` block contains:
59+
- `internal_bandwidth` - The internal bandwidth of the server type (in bytes/second).
60+
- `public_bandwidth` - The public bandwidth of the server type (in bytes/second).
61+
- `block_bandwidth` - The block bandwidth of the server type (in bytes/second).
62+
63+
- `hourly_price` - The hourly price of the server type (in euros).
64+
65+
- `monthly_price` - The monthly price of the server type (in euros).
66+
67+
- `end_of_service` - Whether the server type will soon reach End Of Service.
68+
69+
- `availability` - Whether the server type is available in the zone.

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ func Provider(config *Config) plugin.ProviderFunc {
292292
"scaleway_instance_security_group": instance.DataSourceSecurityGroup(),
293293
"scaleway_instance_server": instance.DataSourceServer(),
294294
"scaleway_instance_servers": instance.DataSourceServers(),
295+
"scaleway_instance_server_type": instance.DataSourceServerType(),
295296
"scaleway_instance_snapshot": instance.DataSourceSnapshot(),
296297
"scaleway_instance_volume": instance.DataSourceVolume(),
297298
"scaleway_iot_device": iot.DataSourceDevice(),
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
package instance
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
9+
product_catalog "github.com/scaleway/scaleway-sdk-go/api/product_catalog/v2alpha1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
13+
)
14+
15+
func DataSourceServerType() *schema.Resource {
16+
return &schema.Resource{
17+
ReadContext: DataSourceInstanceServerTypeRead,
18+
Schema: map[string]*schema.Schema{
19+
"name": {
20+
Type: schema.TypeString,
21+
Required: true,
22+
Description: "The name of the server type",
23+
},
24+
"arch": {
25+
Type: schema.TypeString,
26+
Computed: true,
27+
Description: "The architecture of the server type",
28+
},
29+
"cpu": {
30+
Type: schema.TypeInt,
31+
Computed: true,
32+
Description: "The number of CPU cores of the server type",
33+
},
34+
"ram": {
35+
Type: schema.TypeInt,
36+
Computed: true,
37+
Description: "The number of bytes of RAM of the server type",
38+
},
39+
"gpu": {
40+
Type: schema.TypeInt,
41+
Computed: true,
42+
Description: "The number of GPUs of the server type",
43+
},
44+
"volumes": {
45+
Type: schema.TypeList,
46+
Computed: true,
47+
Description: "The specifications of volumes allowed for the server type",
48+
Elem: &schema.Resource{
49+
Schema: map[string]*schema.Schema{
50+
"min_size_total": {
51+
Type: schema.TypeInt,
52+
Computed: true,
53+
Description: "The minimum total size in bytes of volumes allowed on the server type",
54+
},
55+
"max_size_total": {
56+
Type: schema.TypeInt,
57+
Computed: true,
58+
Description: "The maximum total size in bytes of volumes allowed on the server type",
59+
},
60+
"min_size_per_local_volume": {
61+
Type: schema.TypeInt,
62+
Computed: true,
63+
Description: "The minimum size in bytes per local volume allowed on the server type",
64+
},
65+
"max_size_per_local_volume": {
66+
Type: schema.TypeInt,
67+
Computed: true,
68+
Description: "The maximum size in bytes per local volume allowed on the server type",
69+
},
70+
"scratch_storage_max_size": {
71+
Type: schema.TypeInt,
72+
Computed: true,
73+
Description: "The maximum size in bytes of the scratch volume allowed on the server type",
74+
},
75+
"block_storage": {
76+
Type: schema.TypeBool,
77+
Computed: true,
78+
Description: "Whether block storage is allowed on the server type",
79+
},
80+
},
81+
},
82+
},
83+
"capabilities": {
84+
Type: schema.TypeList,
85+
Computed: true,
86+
Description: "The specific capabilities of the server type",
87+
Elem: &schema.Resource{
88+
Schema: map[string]*schema.Schema{
89+
"boot_types": {
90+
Type: schema.TypeList,
91+
Computed: true,
92+
Description: "The list of boot types allowed for the server type",
93+
Elem: &schema.Schema{
94+
Type: schema.TypeString,
95+
},
96+
},
97+
"max_file_systems": {
98+
Type: schema.TypeInt,
99+
Computed: true,
100+
Description: "The maximum number of file systems that can be attached to the server type",
101+
},
102+
},
103+
},
104+
},
105+
"network": {
106+
Type: schema.TypeList,
107+
Computed: true,
108+
Description: "The network specifications of the server type",
109+
Elem: &schema.Resource{
110+
Schema: map[string]*schema.Schema{
111+
"internal_bandwidth": {
112+
Type: schema.TypeInt,
113+
Computed: true,
114+
Description: "The internal bandwidth of the server type",
115+
},
116+
"public_bandwidth": {
117+
Type: schema.TypeInt,
118+
Computed: true,
119+
Description: "The public bandwidth of the server type",
120+
},
121+
"block_bandwidth": {
122+
Type: schema.TypeInt,
123+
Computed: true,
124+
Description: "The block bandwidth of the server type",
125+
},
126+
},
127+
},
128+
},
129+
"hourly_price": {
130+
Type: schema.TypeFloat,
131+
Computed: true,
132+
Description: "The hourly price of the server type in euro",
133+
},
134+
"end_of_service": {
135+
Type: schema.TypeBool,
136+
Computed: true,
137+
Description: "Whether the server type will soon reach End Of Service",
138+
},
139+
"availability": {
140+
Type: schema.TypeString,
141+
Computed: true,
142+
Description: "Whether the server type is available in the zone",
143+
},
144+
"zone": zonal.Schema(),
145+
},
146+
}
147+
}
148+
149+
func DataSourceInstanceServerTypeRead(ctx context.Context, d *schema.ResourceData, i any) diag.Diagnostics {
150+
instanceAPI, zone, err := newAPIWithZone(d, i)
151+
if err != nil {
152+
return diag.FromErr(err)
153+
}
154+
155+
serverTypes, err := instanceAPI.ListServersTypes(&instance.ListServersTypesRequest{
156+
Zone: zone,
157+
}, scw.WithAllPages(), scw.WithContext(ctx))
158+
if err != nil {
159+
return diag.FromErr(err)
160+
}
161+
162+
name := d.Get("name").(string)
163+
164+
serverType, ok := serverTypes.Servers[name]
165+
if !ok {
166+
return diag.Errorf("server type %s not found", name)
167+
}
168+
169+
d.SetId(name)
170+
_ = d.Set("name", name)
171+
_ = d.Set("zone", zone)
172+
_ = d.Set("arch", serverType.Arch)
173+
_ = d.Set("cpu", int(serverType.Ncpus))
174+
_ = d.Set("ram", int(serverType.RAM))
175+
_ = d.Set("volumes", flattenVolumeConstraints(serverType))
176+
_ = d.Set("capabilities", flattenCapabilities(serverType.Capabilities))
177+
_ = d.Set("network", flattenNetwork(serverType))
178+
_ = d.Set("end_of_service", serverType.EndOfService)
179+
180+
if serverType.Gpu != nil {
181+
_ = d.Set("gpu", int(*serverType.Gpu))
182+
}
183+
184+
// Price (needs to be fetched from the Product Catalog)
185+
pcuAPI := product_catalog.NewPublicCatalogAPI(meta.ExtractScwClient(i))
186+
187+
pcuInstances, err := pcuAPI.ListPublicCatalogProducts(&product_catalog.PublicCatalogAPIListPublicCatalogProductsRequest{
188+
ProductTypes: []product_catalog.ListPublicCatalogProductsRequestProductType{
189+
product_catalog.ListPublicCatalogProductsRequestProductTypeInstance,
190+
},
191+
Zone: &zone,
192+
}, scw.WithAllPages(), scw.WithContext(ctx))
193+
if err != nil {
194+
return diag.FromErr(err)
195+
}
196+
197+
for _, pcuInstance := range pcuInstances.Products {
198+
if pcuInstance.Properties.Instance.OfferID != name {
199+
continue
200+
}
201+
202+
_ = d.Set("hourly_price", pcuInstance.Price.RetailPrice.ToFloat())
203+
}
204+
205+
// Availability
206+
availabilitiesResponse, err := instanceAPI.GetServerTypesAvailability(&instance.GetServerTypesAvailabilityRequest{
207+
Zone: zone,
208+
}, scw.WithAllPages(), scw.WithContext(ctx))
209+
if err != nil {
210+
return diag.FromErr(err)
211+
}
212+
213+
if availability, exists := availabilitiesResponse.Servers[name]; exists {
214+
_ = d.Set("availability", availability.Availability.String())
215+
}
216+
217+
return nil
218+
}
219+
220+
func flattenVolumeConstraints(serverType *instance.ServerType) []map[string]any {
221+
flattened := map[string]any{}
222+
223+
if serverType.VolumesConstraint != nil {
224+
flattened["min_size_total"] = serverType.VolumesConstraint.MinSize
225+
flattened["max_size_total"] = serverType.VolumesConstraint.MaxSize
226+
}
227+
228+
if serverType.PerVolumeConstraint != nil && serverType.PerVolumeConstraint.LSSD != nil {
229+
flattened["min_size_per_local_volume"] = serverType.PerVolumeConstraint.LSSD.MinSize
230+
flattened["max_size_per_local_volume"] = serverType.PerVolumeConstraint.LSSD.MaxSize
231+
}
232+
233+
if serverType.ScratchStorageMaxSize != nil {
234+
flattened["scratch_storage_max_size"] = serverType.ScratchStorageMaxSize
235+
}
236+
237+
if serverType.Capabilities != nil && serverType.Capabilities.BlockStorage != nil {
238+
flattened["block_storage"] = *serverType.Capabilities.BlockStorage
239+
}
240+
241+
return []map[string]any{flattened}
242+
}
243+
244+
func flattenCapabilities(capabilities *instance.ServerTypeCapabilities) []map[string]any {
245+
if capabilities == nil {
246+
return nil
247+
}
248+
249+
bootTypes := []string(nil)
250+
for _, bootType := range capabilities.BootTypes {
251+
bootTypes = append(bootTypes, bootType.String())
252+
}
253+
254+
flattened := map[string]any{
255+
"max_file_systems": capabilities.MaxFileSystems,
256+
"boot_types": bootTypes,
257+
}
258+
259+
return []map[string]any{flattened}
260+
}
261+
262+
func flattenNetwork(serverType *instance.ServerType) []map[string]any {
263+
if serverType.Network == nil {
264+
return nil
265+
}
266+
267+
flattened := map[string]any{}
268+
269+
if serverType.Network.SumInternalBandwidth != nil {
270+
flattened["internal_bandwidth"] = *serverType.Network.SumInternalBandwidth
271+
}
272+
273+
if serverType.Network.SumInternetBandwidth != nil {
274+
flattened["public_bandwidth"] = *serverType.Network.SumInternetBandwidth
275+
}
276+
277+
if serverType.BlockBandwidth != nil {
278+
flattened["block_bandwidth"] = *serverType.BlockBandwidth
279+
}
280+
281+
return []map[string]any{flattened}
282+
}

0 commit comments

Comments
 (0)