Skip to content

Commit 1fbc1dd

Browse files
yfodilremyleone
andauthored
feat(vpc): add routes datasource (#2621)
* feat(vpc): add routes datasource * fix test and add cassette * add doc * update cassette * add descriptions and fixes * update dead links --------- Co-authored-by: Rémy Léone <[email protected]>
1 parent 4e7279e commit 1fbc1dd

File tree

8 files changed

+5518
-2
lines changed

8 files changed

+5518
-2
lines changed

docs/data-sources/marketplace_image.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ data "scaleway_marketplace_image" "my_image" {
1717

1818
## Argument Reference
1919

20-
- `label` - (Required) Exact label of the desired image. You can use [this endpoint](https://api-marketplace.scaleway.com/images?page=1&per_page=100)
20+
- `label` - (Required) Exact label of the desired image. You can use [this endpoint](https://www.scaleway.com/en/developers/api/marketplace/#path-marketplace-images-list-marketplace-images)
2121
to find the right `label`.
2222

2323
- `instance_type` - (Optional, default `DEV1-S`) The instance type the image is compatible with.

docs/data-sources/vpc_routes.md

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
subcategory: "VPC"
3+
page_title: "Scaleway: scaleway_vpc_routes"
4+
---
5+
6+
# scaleway_vpc_routes
7+
8+
Gets information about multiple VPC routes.
9+
10+
## Example Usage
11+
12+
```hcl
13+
resource scaleway_vpc vpc01 {
14+
name = "tf-vpc-route"
15+
enable_routing = true
16+
}
17+
18+
resource scaleway_vpc_private_network pn01 {
19+
name = "tf-pn-route"
20+
vpc_id = scaleway_vpc.vpc01.id
21+
}
22+
23+
resource scaleway_vpc_private_network pn02 {
24+
name = "tf-pn_route-2"
25+
vpc_id = scaleway_vpc.vpc01.id
26+
}
27+
28+
# Find routes with a matching VPC ID
29+
data "scaleway_vpc_routes" "routes_by_vpc_id" {
30+
vpc_id = scaleway_vpc.vpc01.id
31+
}
32+
33+
# Find routes with a matching next hop private network ID
34+
data "scaleway_vpc_routes" "routes_by_pn_id" {
35+
vpc_id = scaleway_vpc.vpc01.id
36+
nexthop_private_network_id = scaleway_vpc_private_network.pn01.id
37+
}
38+
39+
# Find routes with an IPv6 destination
40+
data "scaleway_vpc_routes" "routes_by_pn_id" {
41+
vpc_id = scaleway_vpc.vpc01.id
42+
is_ipv6 = true
43+
}
44+
45+
# Find routes with a nexthop resource type
46+
data "scaleway_vpc_routes" "routes_by_pn_id" {
47+
vpc_id = scaleway_vpc.vpc01.id
48+
nexthop_resource_type = "vpc_gateway_network"
49+
}
50+
```
51+
52+
## Argument Reference
53+
54+
- `vpc_id` - (Optional) The VPC ID to filter for. routes with a similar VPC ID are listed.
55+
56+
- `nexthop_resource_id` - (Optional) The next hop resource ID to filter for. routes with a similar next hop resource ID are listed.
57+
58+
- `nexthop_private_network_id` - (Optional) The next hop private network ID to filter for. routes with a similar next hop private network ID are listed.
59+
60+
- `nexthop_resource_type` - (Optional) The next hop resource type to filter for. routes with a similar next hop resource type are listed.
61+
62+
- `is_ipv6` - (Optional) Routes with an IPv6 destination will be listed.
63+
64+
- `tags` - (Optional) List of tags to filter for. routes with these exact tags are listed.
65+
66+
- `region` - (Defaults to [provider](../index.md#region) `region`). The [region](../guides/regions_and_zones.md#regions) in which the routes exist.
67+
68+
## Attributes Reference
69+
70+
In addition to all arguments above, the following attributes are exported:
71+
72+
- `routes` - List of retrieved routes
73+
- `id` - The ID of the route.
74+
~> **Important:** route 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
75+
- `created_at` - The date on which the route was created (RFC 3339 format).
76+
- `destination` - The destination IP or IP range of the route.
77+
- `description` - The description of the route.
78+
- `nexthop_ip` - The IP of the route's next hop.
79+
- `nexthop_name` - The name of the route's next hop.

docs/resources/instance_server.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ Use `replace_on_type_change` to trigger replacement instead of migration.
174174

175175
~> **Important:** If `type` change and migration occurs, the server will be stopped and changed backed to its original state. It will be started again if it was running.
176176

177-
- `image` - (Optional) The UUID or the label of the base image used by the server. You can use [this endpoint](https://api-marketplace.scaleway.com/images?page=1&per_page=100)
177+
- `image` - (Optional) The UUID or the label of the base image used by the server. You can use [this endpoint](https://www.scaleway.com/en/developers/api/marketplace/#path-marketplace-images-list-marketplace-images)
178178
to find either the right `label` or the right local image `ID` for a given `type`. Optional when creating an instance with an existing root volume.
179179

180180
You can check the available labels with our [CLI](https://www.scaleway.com/en/docs/compute/instances/api-cli/creating-managing-instances-with-cliv2/). ```scw marketplace image list```

internal/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ func Provider(config *Config) plugin.ProviderFunc {
306306
"scaleway_vpc_public_gateway_dhcp_reservation": vpcgw.DataSourceDHCPReservation(),
307307
"scaleway_vpc_public_gateway_ip": vpcgw.DataSourceIP(),
308308
"scaleway_vpc_public_gateway_pat_rule": vpcgw.DataSourcePATRule(),
309+
"scaleway_vpc_routes": vpc.DataSourceRoutes(),
309310
"scaleway_vpcs": vpc.DataSourceVPCs(),
310311
"scaleway_webhosting": webhosting.DataSourceWebhosting(),
311312
"scaleway_webhosting_offer": webhosting.DataSourceOffer(),

internal/services/vpc/helpers.go

+11
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ func NewAPI(m interface{}) (*vpc.API, error) {
4444
return vpc.NewAPI(meta.ExtractScwClient(m)), nil
4545
}
4646

47+
// routesAPIWithRegion returns a new VPC API and the region for a Create request
48+
func routesAPIWithRegion(d *schema.ResourceData, m interface{}) (*vpc.RoutesWithNexthopAPI, scw.Region, error) {
49+
routesAPI := vpc.NewRoutesWithNexthopAPI(meta.ExtractScwClient(m))
50+
51+
region, err := meta.ExtractRegion(d, m)
52+
if err != nil {
53+
return nil, "", err
54+
}
55+
return routesAPI, region, err
56+
}
57+
4758
func vpcPrivateNetworkUpgradeV1SchemaType() cty.Type {
4859
return cty.Object(map[string]cty.Type{
4960
"id": cty.String,
+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package vpc
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/vpc/v2"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
10+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
11+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
14+
)
15+
16+
func DataSourceRoutes() *schema.Resource {
17+
return &schema.Resource{
18+
ReadContext: DataSourceRoutesRead,
19+
Schema: map[string]*schema.Schema{
20+
"vpc_id": {
21+
Type: schema.TypeString,
22+
Optional: true,
23+
Description: "Only routes within this VPC will be returned",
24+
},
25+
"nexthop_resource_id": {
26+
Type: schema.TypeString,
27+
Optional: true,
28+
Description: "Only routes with a matching next hop resource ID will be returned",
29+
},
30+
"nexthop_private_network_id": {
31+
Type: schema.TypeString,
32+
Optional: true,
33+
Description: "Only routes with a matching next hop private network ID will be returned",
34+
},
35+
"nexthop_resource_type": {
36+
Type: schema.TypeString,
37+
Optional: true,
38+
Description: "Only Routes with a matching next hop resource type will be returned",
39+
ValidateDiagFunc: verify.ValidateEnum[vpc.RouteWithNexthopResourceType](),
40+
},
41+
"is_ipv6": {
42+
Type: schema.TypeBool,
43+
Optional: true,
44+
Description: "Only routes with an IPv6 destination will be returned",
45+
},
46+
"tags": {
47+
Type: schema.TypeList,
48+
Elem: &schema.Schema{
49+
Type: schema.TypeString,
50+
},
51+
Optional: true,
52+
Description: "Routes with these exact tags are listed.",
53+
},
54+
"routes": {
55+
Type: schema.TypeList,
56+
Computed: true,
57+
Elem: &schema.Resource{
58+
Schema: map[string]*schema.Schema{
59+
"id": {
60+
Computed: true,
61+
Type: schema.TypeString,
62+
Description: "The associated route ID",
63+
},
64+
"vpc_id": {
65+
Computed: true,
66+
Type: schema.TypeString,
67+
Description: "The VPC ID associated with the route",
68+
},
69+
"tags": {
70+
Computed: true,
71+
Type: schema.TypeList,
72+
Elem: &schema.Schema{
73+
Type: schema.TypeString,
74+
},
75+
Description: "The tags associated with the route",
76+
},
77+
"created_at": {
78+
Computed: true,
79+
Type: schema.TypeString,
80+
Description: "Date and time of route's creation (RFC 3339 format)",
81+
},
82+
"description": {
83+
Computed: true,
84+
Type: schema.TypeString,
85+
Description: "The description of the route",
86+
},
87+
"destination": {
88+
Computed: true,
89+
Type: schema.TypeString,
90+
Description: "The destination IP or IP range of the route",
91+
},
92+
"nexthop_resource_id": {
93+
Computed: true,
94+
Type: schema.TypeString,
95+
Description: "The resource ID of the route's next hop",
96+
},
97+
"nexthop_private_network_id": {
98+
Computed: true,
99+
Type: schema.TypeString,
100+
Description: "The private network ID of the route's next hop",
101+
},
102+
"nexthop_ip": {
103+
Computed: true,
104+
Type: schema.TypeString,
105+
Description: "The IP of the route's next hop",
106+
},
107+
"nexthop_name": {
108+
Computed: true,
109+
Type: schema.TypeString,
110+
Description: "The name of the route's next hop",
111+
},
112+
"nexthop_resource_type": {
113+
Computed: true,
114+
Type: schema.TypeString,
115+
Description: "The resource type of the route's next hop",
116+
},
117+
"region": regional.Schema(),
118+
},
119+
},
120+
},
121+
"region": regional.Schema(),
122+
},
123+
}
124+
}
125+
126+
func DataSourceRoutesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
127+
routesAPI, region, err := routesAPIWithRegion(d, m)
128+
if err != nil {
129+
return diag.FromErr(err)
130+
}
131+
132+
req := &vpc.RoutesWithNexthopAPIListRoutesWithNexthopRequest{
133+
Region: region,
134+
Tags: types.ExpandStrings(d.Get("tags")),
135+
VpcID: types.ExpandStringPtr(locality.ExpandID(d.Get("vpc_id"))),
136+
NexthopResourceID: types.ExpandStringPtr(locality.ExpandID(d.Get("nexthop_resource_id"))),
137+
NexthopPrivateNetworkID: types.ExpandStringPtr(locality.ExpandID(d.Get("nexthop_private_network_id"))),
138+
NexthopResourceType: vpc.RouteWithNexthopResourceType(d.Get("nexthop_resource_type").(string)),
139+
}
140+
141+
isipv6, isipv6Exists := d.GetOk("is_ipv6")
142+
if isipv6Exists {
143+
req.IsIPv6 = types.ExpandBoolPtr(isipv6)
144+
}
145+
146+
res, err := routesAPI.ListRoutesWithNexthop(req, scw.WithContext(ctx))
147+
if err != nil {
148+
return diag.FromErr(err)
149+
}
150+
151+
routes := []interface{}(nil)
152+
for _, route := range res.Routes {
153+
rawRoute := make(map[string]interface{})
154+
if route.Route != nil {
155+
rawRoute["id"] = regional.NewIDString(region, route.Route.ID)
156+
rawRoute["created_at"] = types.FlattenTime(route.Route.CreatedAt)
157+
rawRoute["vpc_id"] = route.Route.VpcID
158+
rawRoute["nexthop_resource_id"] = types.FlattenStringPtr(route.Route.NexthopResourceID)
159+
rawRoute["nexthop_private_network_id"] = types.FlattenStringPtr(route.Route.NexthopPrivateNetworkID)
160+
rawRoute["description"] = route.Route.Description
161+
rawRoute["region"] = region.String()
162+
163+
destination, err := types.FlattenIPNet(route.Route.Destination)
164+
if err != nil {
165+
return diag.FromErr(err)
166+
}
167+
rawRoute["destination"] = destination
168+
169+
if len(route.Route.Tags) > 0 {
170+
rawRoute["tags"] = route.Route.Tags
171+
}
172+
}
173+
rawRoute["nexthop_ip"] = types.FlattenIPPtr(route.NexthopIP)
174+
rawRoute["nexthop_name"] = types.FlattenStringPtr(route.NexthopName)
175+
rawRoute["nexthop_resource_type"] = route.NexthopResourceType.String()
176+
177+
routes = append(routes, rawRoute)
178+
}
179+
180+
d.SetId(region.String())
181+
_ = d.Set("routes", routes)
182+
183+
return nil
184+
}

0 commit comments

Comments
 (0)