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(vpc): add routes datasource #2621

Merged
merged 8 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
73 changes: 73 additions & 0 deletions docs/data-sources/vpc_routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
subcategory: "VPC"
page_title: "Scaleway: scaleway_vpc_routes"
---

# scaleway_vpc_routes

Gets information about multiple VPC routes.

## Example Usage

```hcl
resource scaleway_vpc vpc01 {
name = "tf-vpc-route"
enable_routing = true
}

resource scaleway_vpc_private_network pn01 {
name = "tf-pn-route"
vpc_id = scaleway_vpc.vpc01.id
}

resource scaleway_vpc_private_network pn02 {
name = "tf-pn_route-2"
vpc_id = scaleway_vpc.vpc01.id
}

# Find routes with a matching VPC ID
data "scaleway_vpc_routes" "routes_by_vpc_id" {
vpc_id = scaleway_vpc.vpc01.id
}

# Find routes with a matching next hop private network ID
data "scaleway_vpc_routes" "routes_by_pn_id" {
vpc_id = scaleway_vpc.vpc01.id
nexthop_private_network_id = scaleway_vpc_private_network.pn01.id
}

# Find routes with an IPv6 destination
data "scaleway_vpc_routes" "routes_by_pn_id" {
vpc_id = scaleway_vpc.vpc01.id
is_ipv6 = true
}
```

## Argument Reference

- `vpc_id` - (Optional) The VPC ID to filter for. routes with a similar VPC ID are listed.

- `nexthop_resource_id` - (Optional) The next hop resource ID to filter for. routes with a similar next hop resource ID are listed.

- `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.

- `nexthop_resource_type` - (Optional) The next hop resource type to filter for. routes with a similar next hop resource type are listed.

- `is_ipv6` - (Optional) Routes with an IPv6 destination will be listed.

- `tags` - (Optional) List of tags to filter for. routes with these exact tags are listed.

- `region` - (Defaults to [provider](../index.md#region) `region`). The [region](../guides/regions_and_zones.md#regions) in which the routes exist.

## Attributes Reference

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

- `routes` - List of retrieved routes
- `id` - The associated route ID.
~> **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
- `created_at` - Date and time of route's creation (RFC 3339 format).
- `destination` - Yhe destination IP or IP range of the route.
- `description` - The description of the route.
- `nexthop_ip` - The IP of the route's next hop.
- `nexthop_name` - The name of the route's next hop.
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ func Provider(config *Config) plugin.ProviderFunc {
"scaleway_vpc_public_gateway_dhcp_reservation": vpcgw.DataSourceDHCPReservation(),
"scaleway_vpc_public_gateway_ip": vpcgw.DataSourceIP(),
"scaleway_vpc_public_gateway_pat_rule": vpcgw.DataSourcePATRule(),
"scaleway_vpc_routes": vpc.DataSourceRoutes(),
"scaleway_vpcs": vpc.DataSourceVPCs(),
"scaleway_webhosting": webhosting.DataSourceWebhosting(),
"scaleway_webhosting_offer": webhosting.DataSourceOffer(),
Expand Down
11 changes: 11 additions & 0 deletions internal/services/vpc/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ func NewAPI(m interface{}) (*vpc.API, error) {
return vpc.NewAPI(meta.ExtractScwClient(m)), nil
}

// routesAPIWithRegion returns a new VPC API and the region for a Create request
func routesAPIWithRegion(d *schema.ResourceData, m interface{}) (*vpc.RoutesWithNexthopAPI, scw.Region, error) {
routesAPI := vpc.NewRoutesWithNexthopAPI(meta.ExtractScwClient(m))

region, err := meta.ExtractRegion(d, m)
if err != nil {
return nil, "", err
}
return routesAPI, region, err
}

func vpcPrivateNetworkUpgradeV1SchemaType() cty.Type {
return cty.Object(map[string]cty.Type{
"id": cty.String,
Expand Down
173 changes: 173 additions & 0 deletions internal/services/vpc/routes_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package vpc

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
)

func DataSourceRoutes() *schema.Resource {
return &schema.Resource{
ReadContext: DataSourceRoutesRead,
Schema: map[string]*schema.Schema{
"vpc_id": {
Type: schema.TypeString,
Optional: true,
Description: "Only routes within this VPC will be returned",
},
"nexthop_resource_id": {
Type: schema.TypeString,
Optional: true,
Description: "Only routes with a matching next hop resource ID will be returned",
},
"nexthop_private_network_id": {
Type: schema.TypeString,
Optional: true,
Description: "Only routes with a matching next hop private network ID will be returned",
},
"nexthop_resource_type": {
Type: schema.TypeString,
Optional: true,
Description: "Only Routes with a matching next hop resource type will be returned",
ValidateDiagFunc: verify.ValidateEnum[vpc.RouteWithNexthopResourceType](),
},
"is_ipv6": {
Type: schema.TypeBool,
Optional: true,
Description: "Only routes with an IPv6 destination will be returned",
},
"tags": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Description: "Routes with these exact tags are listed.",
},
"routes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Computed: true,
Type: schema.TypeString,
},
"vpc_id": {
Computed: true,
Type: schema.TypeString,
},
"tags": {
Computed: true,
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"created_at": {
Computed: true,
Type: schema.TypeString,
},
"description": {
Computed: true,
Type: schema.TypeString,
},
"destination": {
Computed: true,
Type: schema.TypeString,
},
"nexthop_resource_id": {
Computed: true,
Type: schema.TypeString,
},
"nexthop_private_network_id": {
Computed: true,
Type: schema.TypeString,
},
"nexthop_ip": {
Computed: true,
Type: schema.TypeString,
},
"nexthop_name": {
Computed: true,
Type: schema.TypeString,
},
"nexthop_resource_type": {
Computed: true,
Type: schema.TypeString,
},
"region": regional.Schema(),
},
},
},
"region": regional.Schema(),
},
}
}

func DataSourceRoutesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
routesAPI, region, err := routesAPIWithRegion(d, m)
if err != nil {
return diag.FromErr(err)
}

req := &vpc.RoutesWithNexthopAPIListRoutesWithNexthopRequest{
Region: region,
Tags: types.ExpandStrings(d.Get("tags")),
VpcID: types.ExpandStringPtr(locality.ExpandID(d.Get("vpc_id"))),
NexthopResourceID: types.ExpandStringPtr(locality.ExpandID(d.Get("nexthop_resource_id"))),
NexthopPrivateNetworkID: types.ExpandStringPtr(locality.ExpandID(d.Get("nexthop_private_network_id"))),
NexthopResourceType: vpc.RouteWithNexthopResourceType(d.Get("nexthop_resource_type").(string)),
}

isipv6, isipv6Exists := d.GetOk("is_ipv6")
if isipv6Exists {
req.IsIPv6 = types.ExpandBoolPtr(isipv6)
}

res, err := routesAPI.ListRoutesWithNexthop(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

routes := []interface{}(nil)
for _, route := range res.Routes {
rawRoute := make(map[string]interface{})
if route.Route != nil {
rawRoute["id"] = regional.NewIDString(region, route.Route.ID)
rawRoute["created_at"] = types.FlattenTime(route.Route.CreatedAt)
rawRoute["vpc_id"] = route.Route.VpcID
rawRoute["nexthop_resource_id"] = types.FlattenStringPtr(route.Route.NexthopResourceID)
rawRoute["nexthop_private_network_id"] = types.FlattenStringPtr(route.Route.NexthopPrivateNetworkID)
rawRoute["description"] = route.Route.Description
rawRoute["region"] = region.String()

destination, err := types.FlattenIPNet(route.Route.Destination)
if err != nil {
return diag.FromErr(err)
}
rawRoute["destination"] = destination

if len(route.Route.Tags) > 0 {
rawRoute["tags"] = route.Route.Tags
}
}
rawRoute["nexthop_ip"] = types.FlattenIPPtr(route.NexthopIP)
rawRoute["nexthop_name"] = types.FlattenStringPtr(route.NexthopName)
rawRoute["nexthop_resource_type"] = route.NexthopResourceType.String()

routes = append(routes, rawRoute)
}

d.SetId(region.String())
_ = d.Set("routes", routes)

return nil
}
Loading
Loading