diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 05872d5b5b..c34af69c10 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -45,6 +45,7 @@ jobs: - rdb - redis - registry + - s2svpn - sdb - secret - tem diff --git a/docs/resources/s2s_vpn_connection.md b/docs/resources/s2s_vpn_connection.md new file mode 100644 index 0000000000..9ba10792a4 --- /dev/null +++ b/docs/resources/s2s_vpn_connection.md @@ -0,0 +1,162 @@ +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_connection" +--- + +# Resource: scaleway_s2s_vpn_connection + +Creates and manages Scaleway Site-to-Site VPN Connections. +A connection links a Scaleway VPN Gateway to a Customer Gateway and establishes an IPSec tunnel with BGP routing. + +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic Connection + +```terraform +resource "scaleway_vpc" "vpc" { + name = "my-vpc" +} + +resource "scaleway_vpc_private_network" "pn" { + name = "my-private-network" + vpc_id = scaleway_vpc.vpc.id + ipv4_subnet { + subnet = "10.0.1.0/24" + } +} + +resource "scaleway_s2s_vpn_gateway" "gateway" { + name = "my-vpn-gateway" + gateway_type = "VGW-S" + private_network_id = scaleway_vpc_private_network.pn.id +} + +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = "203.0.113.1" + asn = 65000 +} + +resource "scaleway_s2s_vpn_routing_policy" "policy" { + name = "my-routing-policy" + prefix_filter_in = ["10.0.2.0/24"] + prefix_filter_out = ["10.0.1.0/24"] +} + +resource "scaleway_s2s_vpn_connection" "main" { + name = "my-vpn-connection" + vpn_gateway_id = scaleway_s2s_vpn_gateway.gateway.id + customer_gateway_id = scaleway_s2s_vpn_customer_gateway.customer_gw.id + initiation_policy = "customer_gateway" + enable_route_propagation = true + + bgp_config_ipv4 { + routing_policy_id = scaleway_s2s_vpn_routing_policy.policy.id + private_ip = "169.254.0.1/30" + peer_private_ip = "169.254.0.2/30" + } + + ikev2_ciphers { + encryption = "aes256" + integrity = "sha256" + dh_group = "modp2048" + } + + esp_ciphers { + encryption = "aes256" + integrity = "sha256" + dh_group = "modp2048" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `vpn_gateway_id` - (Required) The ID of the VPN gateway to attach to the connection. +- `customer_gateway_id` - (Required) The ID of the customer gateway to attach to the connection. +- `initiation_policy` - (Optional) Defines who initiates the IPSec tunnel. +- `enable_route_propagation` - (Optional) Defines whether route propagation is enabled or not. +- `bgp_config_ipv4` - (Optional) BGP configuration for IPv4. See [BGP Config](#bgp-config) below. +- `bgp_config_ipv6` - (Optional) BGP configuration for IPv6. See [BGP Config](#bgp-config) below. +- `ikev2_ciphers` - (Optional) IKEv2 cipher configuration for Phase 1 (tunnel establishment). See [Cipher Config](#cipher-config) below. +- `esp_ciphers` - (Optional) ESP cipher configuration for Phase 2 (data encryption). See [Cipher Config](#cipher-config) below. +- `name` - (Optional) The name of the connection. +- `tags` - (Optional) The list of tags to apply to the connection. +- `is_ipv6` - (Optional) Defines IP version of the IPSec Tunnel. Defaults to `false` (IPv4). +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the connection should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the connection is associated with. + +### BGP Config + +The `bgp_config_ipv4` and `bgp_config_ipv6` blocks support: + +- `routing_policy_id` - (Required) The ID of the routing policy to use for BGP route filtering. +- `private_ip` - (Optional) The BGP peer IP on Scaleway side (within the IPSec tunnel), in CIDR notation (e.g., `169.254.0.1/30`). If not provided, Scaleway will assign it automatically. +- `peer_private_ip` - (Optional) The BGP peer IP on customer side (within the IPSec tunnel), in CIDR notation (e.g., `169.254.0.2/30`). If not provided, Scaleway will assign it automatically. + +### Cipher Config + +The `ikev2_ciphers` and `esp_ciphers` blocks support: + +- `encryption` - (Required) The encryption algorithm. +- `integrity` - (Optional) The integrity/hash algorithm. +- `dh_group` - (Optional) The Diffie-Hellman group. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the connection. +- `status` - The status of the connection. +- `tunnel_status` - The status of the IPSec tunnel. +- `bgp_status_ipv4` - The status of the BGP IPv4 session. +- `bgp_status_ipv6` - The status of the BGP IPv6 session. +- `bgp_session_ipv4` - The BGP IPv4 session information. See [BGP Session](#bgp-session) below. +- `bgp_session_ipv6` - The BGP IPv6 session information. See [BGP Session](#bgp-session) below. +- `secret_id` - The ID of the secret containing the pre-shared key (PSK) for the connection. +- `secret_version` - The version of the secret containing the PSK. +- `route_propagation_enabled` - Whether route propagation is enabled. +- `created_at` - The date and time of the creation of the connection (RFC 3339 format). +- `updated_at` - The date and time of the last update of the connection (RFC 3339 format). +- `organization_id` - The Organization ID the connection is associated with. + +### BGP Session + +The `bgp_session_ipv4` and `bgp_session_ipv6` blocks contain (read-only): + +- `routing_policy_id` - The routing policy ID used for this BGP session. +- `private_ip` - The BGP peer IP on Scaleway side (within the tunnel). +- `peer_private_ip` - The BGP peer IP on customer side (within the tunnel). + +~> **Important:** Connections' 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` + +~> **Important:** The pre-shared key (PSK) is auto-generated when the connection is created and stored in Scaleway Secret Manager. You can retrieve it using the `scaleway_secret_version` datasource or via the API. + +## Retrieving the Pre-Shared Key (PSK) + +The PSK is stored in Secret Manager and can be retrieved using: + +```terraform +data "scaleway_secret_version" "s2s_psk" { + secret_id = scaleway_s2s_vpn_connection.main.secret_id + revision = tostring(scaleway_s2s_vpn_connection.main.secret_version) +} + +# The PSK is available as base64-encoded data +output "psk" { + value = data.scaleway_secret_version.s2s_psk.data + sensitive = true +} +``` + +## Import + +Connections can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_connection.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/docs/resources/s2s_vpn_customer_gateway.md b/docs/resources/s2s_vpn_customer_gateway.md new file mode 100644 index 0000000000..1fd717bc8b --- /dev/null +++ b/docs/resources/s2s_vpn_customer_gateway.md @@ -0,0 +1,84 @@ +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_customer_gateway" +--- + +# Resource: scaleway_s2s_vpn_customer_gateway + +Creates and manages Scaleway Site-to-Site VPN Customer Gateways. +A customer gateway represents your external VPN endpoint (e.g., a firewall, router, or VPN appliance). + +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic + +```terraform +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = "203.0.113.1" + asn = 65000 +} +``` + +### With IPv6 + +```terraform +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = "203.0.113.1" + ipv6_public = "2001:db8::1" + asn = 65000 +} +``` + +### Using Instance Public IP + +```terraform +resource "scaleway_instance_ip" "vpn_endpoint_ip" {} + +resource "scaleway_instance_server" "vpn_endpoint" { + name = "vpn-endpoint" + type = "DEV1-S" + image = "ubuntu_jammy" + ip_ids = [scaleway_instance_ip.vpn_endpoint_ip.id] +} + +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = scaleway_instance_ip.vpn_endpoint_ip.address + asn = 65000 +} +``` + +## Argument Reference + +The following arguments are supported: + +- `asn` - (Required) The AS Number of the customer gateway. Must be different from Scaleway's ASN (12876). For testing, you can use a private ASN (64512-65535). +- `ipv4_public` - (Optional) The public IPv4 address of the customer gateway (your VPN endpoint). +- `ipv6_public` - (Optional) The public IPv6 address of the customer gateway (your VPN endpoint). +- `name` - (Optional) The name of the customer gateway. If not provided, it will be randomly generated. +- `tags` - (Optional) The list of tags to apply to the customer gateway. +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the customer gateway should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the customer gateway is associated with. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the customer gateway. +- `created_at` - The date and time of the creation of the customer gateway (RFC 3339 format). +- `updated_at` - The date and time of the last update of the customer gateway (RFC 3339 format). +- `organization_id` - The Organization ID the customer gateway is associated with. + +~> **Important:** Customer Gateways' 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` + +## Import + +Customer Gateways can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_customer_gateway.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/docs/resources/s2s_vpn_gateway.md b/docs/resources/s2s_vpn_gateway.md new file mode 100644 index 0000000000..3b0130488a --- /dev/null +++ b/docs/resources/s2s_vpn_gateway.md @@ -0,0 +1,77 @@ +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_gateway" +--- + +# Resource: scaleway_s2s_vpn_gateway + +Creates and manages Scaleway Site-to-Site VPN Gateways. +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic + +```terraform +resource "scaleway_vpc" "vpc" { + name = "my-vpc" +} + +resource "scaleway_vpc_private_network" "pn" { + name = "my-private-network" + vpc_id = scaleway_vpc.vpc.id + ipv4_subnet { + subnet = "10.0.1.0/24" + } +} + +resource "scaleway_s2s_vpn_gateway" "gateway" { + name = "my-vpn-gateway" + gateway_type = "VGW-S" + private_network_id = scaleway_vpc_private_network.pn.id +} +``` + +## Argument Reference + +The following arguments are supported: + +- `gateway_type` - (Required) The VPN gateway type (commercial offer type). +- `private_network_id` - (Required) The ID of the Private Network to attach to the VPN gateway. +- `name` - (Optional) The name of the VPN gateway. If not provided, it will be randomly generated. +- `tags` - (Optional) The list of tags to apply to the VPN gateway. +- `public_config` - (Optional) The public endpoint configuration of the VPN gateway. See [Public Config](#public-config) below. +- `ipam_private_ipv4_id` - (Optional) The ID of the IPAM private IPv4 address to attach to the VPN gateway. +- `ipam_private_ipv6_id` - (Optional) The ID of the IPAM private IPv6 address to attach to the VPN gateway. +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the VPN gateway should be created. +- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the VPN gateway should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the VPN gateway is associated with. + +### Public Config + +The `public_config` block supports: + +- `ipam_ipv4_id` - (Optional) The ID of the IPAM IPv4 address to use as the public IP for the VPN gateway. +- `ipam_ipv6_id` - (Optional) The ID of the IPAM IPv6 address to use as the public IP for the VPN gateway. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the VPN gateway. +- `asn` - The AS Number of the VPN gateway (typically 12876 for Scaleway). +- `status` - The status of the VPN gateway. +- `public_config` - The public endpoint configuration, including the assigned public IPs. +- `created_at` - The date and time of the creation of the VPN gateway (RFC 3339 format). +- `updated_at` - The date and time of the last update of the VPN gateway (RFC 3339 format). +- `organization_id` - The Organization ID the VPN gateway is associated with. + +~> **Important:** VPN Gateways' 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` + +## Import + +VPN Gateways can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_gateway.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/docs/resources/s2s_vpn_routing_policy.md b/docs/resources/s2s_vpn_routing_policy.md new file mode 100644 index 0000000000..b662b9d8ed --- /dev/null +++ b/docs/resources/s2s_vpn_routing_policy.md @@ -0,0 +1,64 @@ +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_routing_policy" +--- + +# Resource: scaleway_s2s_vpn_routing_policy + +Creates and manages Scaleway Site-to-Site VPN Routing Policies. +A routing policy defines which routes are accepted from and advertised to the peer gateway via BGP. + +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic + +```terraform +resource "scaleway_s2s_vpn_routing_policy" "policy" { + name = "my-routing-policy" + prefix_filter_in = ["10.0.2.0/24"] + prefix_filter_out = ["10.0.1.0/24"] +} +``` + +### Multiple Prefixes + +```terraform +resource "scaleway_s2s_vpn_routing_policy" "policy" { + name = "my-routing-policy" + prefix_filter_in = ["10.0.2.0/24", "10.0.3.0/24"] + prefix_filter_out = ["10.0.1.0/24", "172.16.0.0/16"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `prefix_filter_in` - (Optional) List of IP prefixes (in CIDR notation) to accept from the peer gateway. These are the routes that the customer gateway can announce to Scaleway. +- `prefix_filter_out` - (Optional) List of IP prefixes (in CIDR notation) to advertise to the peer gateway. These are the routes that Scaleway will announce to the customer gateway. +- `name` - (Optional) The name of the routing policy. If not provided, it will be randomly generated. +- `tags` - (Optional) The list of tags to apply to the routing policy. +- `is_ipv6` - (Optional) Defines whether the routing policy is for IPv6 prefixes. Defaults to `false` (IPv4). +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the routing policy should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the routing policy is associated with. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the routing policy. +- `created_at` - The date and time of the creation of the routing policy (RFC 3339 format). +- `updated_at` - The date and time of the last update of the routing policy (RFC 3339 format). +- `organization_id` - The Organization ID the routing policy is associated with. + +~> **Important:** Routing Policies' 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` + +## Import + +Routing Policies can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_routing_policy.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/internal/locality/zonal/schemas.go b/internal/locality/zonal/schemas.go index 3250a78ece..863c4d9294 100644 --- a/internal/locality/zonal/schemas.go +++ b/internal/locality/zonal/schemas.go @@ -36,3 +36,14 @@ func Schema() *schema.Schema { DiffSuppressFunc: locality.SuppressSDKNullAssignment, } } + +func OptionalSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The zone you want to attach the resource to", + ValidateDiagFunc: verify.ValidateStringInSliceWithWarning(AllZones(), "zone"), + DiffSuppressFunc: locality.SuppressSDKNullAssignment, + } +} diff --git a/internal/services/container/token.go b/internal/services/container/token.go index 2e0653e4ae..35d184c180 100644 --- a/internal/services/container/token.go +++ b/internal/services/container/token.go @@ -78,7 +78,7 @@ func ResourceContainerTokenCreate(ctx context.Context, d *schema.ResourceData, m return diag.FromErr(err) } - token, err := api.CreateToken(&container.CreateTokenRequest{ + token, err := api.CreateToken(&container.CreateTokenRequest{ //nolint:staticcheck Region: region, ContainerID: types.ExpandStringPtr(locality.ExpandID(d.Get("container_id"))), NamespaceID: types.ExpandStringPtr(locality.ExpandID(d.Get("namespace_id"))), diff --git a/internal/services/function/token.go b/internal/services/function/token.go index 08b6fccad1..ec20612e29 100644 --- a/internal/services/function/token.go +++ b/internal/services/function/token.go @@ -81,7 +81,7 @@ func ResourceFunctionTokenCreate(ctx context.Context, d *schema.ResourceData, m return diag.FromErr(err) } - token, err := api.CreateToken(&function.CreateTokenRequest{ + token, err := api.CreateToken(&function.CreateTokenRequest{ //nolint:staticcheck Region: region, FunctionID: types.ExpandStringPtr(locality.ExpandID(d.Get("function_id"))), NamespaceID: types.ExpandStringPtr(locality.ExpandID(d.Get("namespace_id"))), diff --git a/internal/services/s2svpn/connection.go b/internal/services/s2svpn/connection.go new file mode 100644 index 0000000000..fbe6cff9ed --- /dev/null +++ b/internal/services/s2svpn/connection.go @@ -0,0 +1,404 @@ +package s2svpn + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/verify" +) + +func ResourceConnection() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceConnectionCreate, + ReadContext: ResourceConnectionRead, + UpdateContext: ResourceConnectionUpdate, + DeleteContext: ResourceConnectionDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The name of the connection", + }, + "tags": { + Type: schema.TypeList, + Optional: true, + Description: "The list of tags to apply to the connection", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "is_ipv6": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "Defines IP version of the IPSec Tunnel", + }, + "initiation_policy": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "Defines who initiates the IPsec tunnel", + ValidateDiagFunc: verify.ValidateEnum[s2s_vpn.CreateConnectionRequestInitiationPolicy](), + }, + "ikev2_ciphers": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "The list of IKE v2 ciphers proposed for the IPsec tunnel", + Elem: ResourceConnectionCipher(), + }, + "esp_ciphers": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "The list of ESP ciphers proposed for the IPsec tunnel", + Elem: ResourceConnectionCipher(), + }, + "enable_route_propagation": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "Defines whether route propagation is enabled or not", + }, + "vpn_gateway_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The ID of the VPN gateway to attach to the connection", + }, + "customer_gateway_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The ID of the customer gateway to attach to the connection", + }, + "bgp_config_ipv4": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "The list of IKE v2 ciphers proposed for the IPsec tunnel", + Elem: ResourceConnectionRequestBgpConfig(), + }, + "bgp_config_ipv6": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "The list of IKE v2 ciphers proposed for the IPsec tunnel", + Elem: ResourceConnectionRequestBgpConfig(), + }, + "bgp_status_ipv4": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the BGP IPv4 session", + }, + "bgp_status_ipv6": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the BGP IPv6 session", + }, + "bgp_session_ipv4": { + Type: schema.TypeList, + Computed: true, + Description: "The BGP IPv4 session information (read-only)", + Elem: ResourceConnectionBgpSession(), + }, + "bgp_session_ipv6": { + Type: schema.TypeList, + Computed: true, + Description: "The BGP IPv6 session information (read-only)", + Elem: ResourceConnectionBgpSession(), + }, + "route_propagation_enabled": { + Type: schema.TypeBool, + Description: "Defines whether route propagation is enabled or not", + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the creation of the TLS stage", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the last update of the TLS stage", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the VPN gateway", + }, + "tunnel_status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the VPN gateway", + }, + "secret_id": { + Type: schema.TypeString, + Computed: true, + Description: "The BGP peer IP on customer side", + }, + "secret_version": { + Type: schema.TypeInt, + Computed: true, + Description: "The BGP peer IP on customer side", + }, + "region": regional.Schema(), + "project_id": account.ProjectIDSchema(), + "organization_id": { + Type: schema.TypeString, + Computed: true, + Description: "Organization ID of the Project", + }, + }, + } +} + +func ResourceConnectionCipher() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "encryption": { + Type: schema.TypeString, + Description: "The encryption algorithm", + Required: true, + }, + "integrity": { + Type: schema.TypeString, + Description: "The integrity/hash algorithm", + Optional: true, + }, + "dh_group": { + Type: schema.TypeString, + Description: "The Diffie-Hellman group", + Optional: true, + }, + }, + } +} + +func ResourceConnectionRequestBgpConfig() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "routing_policy_id": { + Type: schema.TypeString, + Description: "The ID of the routing policy to use for BGP route filtering", + Required: true, + }, + "private_ip": { + Type: schema.TypeString, + Description: "The BGP peer IP on Scaleway side", + Optional: true, + }, + "peer_private_ip": { + Type: schema.TypeString, + Description: "The BGP peer IP on customer side", + Optional: true, + }, + }, + } +} + +func ResourceConnectionBgpSession() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "routing_policy_id": { + Type: schema.TypeString, + Computed: true, + Description: "The routing policy ID", + }, + "private_ip": { + Type: schema.TypeString, + Computed: true, + Description: "The BGP peer IP on Scaleway side", + }, + "peer_private_ip": { + Type: schema.TypeString, + Computed: true, + Description: "The BGP peer IP on customer side", + }, + }, + } +} + +func ResourceConnectionCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, err := NewAPIWithRegion(d, m) + if err != nil { + return diag.FromErr(err) + } + + bgpConfigIpv4Config, err := expandConnectionRequestBgpConfig(d.Get("bgp_config_ipv4")) + if err != nil { + return diag.FromErr(err) + } + + bgpConfigIpv6Config, err := expandConnectionRequestBgpConfig(d.Get("bgp_config_ipv6")) + if err != nil { + return diag.FromErr(err) + } + + req := &s2s_vpn.CreateConnectionRequest{ + Region: region, + ProjectID: d.Get("project_id").(string), + Name: types.ExpandOrGenerateString(d.Get("name").(string), "connection"), + Tags: types.ExpandStrings(d.Get("tags")), + IsIPv6: d.Get("is_ipv6").(bool), + EnableRoutePropagation: d.Get("enable_route_propagation").(bool), + InitiationPolicy: s2s_vpn.CreateConnectionRequestInitiationPolicy(d.Get("initiation_policy").(string)), + VpnGatewayID: regional.ExpandID(d.Get("vpn_gateway_id").(string)).ID, + CustomerGatewayID: regional.ExpandID(d.Get("customer_gateway_id").(string)).ID, + Ikev2Ciphers: expandConnectionCiphers(d.Get("ikev2_ciphers")), + EspCiphers: expandConnectionCiphers(d.Get("esp_ciphers")), + } + + if bgpConfigIpv4Config != nil { + req.BgpConfigIPv4 = bgpConfigIpv4Config + } + + if bgpConfigIpv6Config != nil { + req.BgpConfigIPv6 = bgpConfigIpv6Config + } + + res, err := api.CreateConnection(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(regional.NewIDString(region, res.Connection.ID)) + + return ResourceConnectionRead(ctx, d, m) +} + +func ResourceConnectionRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + connection, err := api.GetConnection(&s2s_vpn.GetConnectionRequest{ + ConnectionID: id, + Region: region, + }, scw.WithContext(ctx)) + if err != nil { + if httperrors.Is404(err) { + d.SetId("") + + return nil + } + + return diag.FromErr(err) + } + + _ = d.Set("name", connection.Name) + _ = d.Set("region", connection.Region) + _ = d.Set("project_id", connection.ProjectID) + _ = d.Set("organization_id", connection.OrganizationID) + _ = d.Set("tags", connection.Tags) + _ = d.Set("created_at", types.FlattenTime(connection.CreatedAt)) + _ = d.Set("updated_at", types.FlattenTime(connection.UpdatedAt)) + _ = d.Set("status", connection.Status.String()) + _ = d.Set("is_ipv6", connection.IsIPv6) + _ = d.Set("initiation_policy", connection.InitiationPolicy.String()) + _ = d.Set("route_propagation_enabled", connection.RoutePropagationEnabled) + _ = d.Set("vpn_gateway_id", regional.NewIDString(region, connection.VpnGatewayID)) + _ = d.Set("customer_gateway_id", regional.NewIDString(region, connection.CustomerGatewayID)) + _ = d.Set("tunnel_status", connection.TunnelStatus.String()) + _ = d.Set("ikev2_ciphers", flattenConnectionCiphers(connection.Ikev2Ciphers)) + _ = d.Set("esp_ciphers", flattenConnectionCiphers(connection.EspCiphers)) + _ = d.Set("bgp_status_ipv4", connection.BgpStatusIPv4.String()) + _ = d.Set("bgp_status_ipv6", connection.BgpStatusIPv6.String()) + _ = d.Set("secret_id", regional.NewIDString(region, connection.SecretID)) + _ = d.Set("secret_version", int(connection.SecretRevision)) + + bgpSessionIPv4, err := flattenBGPSession(region, connection.BgpSessionIPv4) + if err != nil { + return diag.FromErr(err) + } + + _ = d.Set("bgp_session_ipv4", bgpSessionIPv4) + + bgpSessionIPv6, err := flattenBGPSession(region, connection.BgpSessionIPv6) + if err != nil { + return diag.FromErr(err) + } + + _ = d.Set("bgp_session_ipv6", bgpSessionIPv6) + + return nil +} + +func ResourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + req := &s2s_vpn.UpdateConnectionRequest{ + Region: region, + ConnectionID: id, + } + + if d.HasChange("name") { + req.Name = types.ExpandUpdatedStringPtr(d.Get("name")) + hasChanged = true + } + + if d.HasChange("tags") { + req.Tags = types.ExpandUpdatedStringsPtr(d.Get("tags")) + hasChanged = true + } + + if d.HasChange("initiation_policy") { + req.InitiationPolicy = s2s_vpn.CreateConnectionRequestInitiationPolicy(d.Get("initiation_policy").(string)) + hasChanged = true + } + + if d.HasChange("ikev2_ciphers") { + req.Ikev2Ciphers = expandConnectionCiphers(d.Get("ikev2_ciphers")) + hasChanged = true + } + + if d.HasChange("esp_ciphers") { + req.EspCiphers = expandConnectionCiphers(d.Get("esp_ciphers")) + hasChanged = true + } + + if hasChanged { + _, err = api.UpdateConnection(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + } + + return ResourceConnectionRead(ctx, d, m) +} + +func ResourceConnectionDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + err = api.DeleteConnection(&s2s_vpn.DeleteConnectionRequest{ + Region: region, + ConnectionID: id, + }, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/s2svpn/connection_test.go b/internal/services/s2svpn/connection_test.go new file mode 100644 index 0000000000..e2773e7db7 --- /dev/null +++ b/internal/services/s2svpn/connection_test.go @@ -0,0 +1,171 @@ +package s2svpn_test + +import ( + "errors" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/s2svpn" +) + +func TestAccConnection_Basic(t *testing.T) { + tt := acctest.NewTestTools(t) + defer tt.Cleanup() + + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: tt.ProviderFactories, + CheckDestroy: resource.ComposeTestCheckFunc( + testAccCheckConnectionDestroy(tt), + testAccCheckVPNGatewayDestroy(tt), + testAccCheckCustomerGatewayDestroy(tt), + testAccCheckRoutingPolicyDestroy(tt), + ), + Steps: []resource.TestStep{ + { + Config: ` + resource "scaleway_vpc" "main" { + name = "tf-test-vpc-connection" + } + + resource "scaleway_vpc_private_network" "main" { + vpc_id = scaleway_vpc.main.id + ipv4_subnet { + subnet = "10.0.0.0/24" + } + } + + resource "scaleway_instance_ip" "customer_ip" {} + + resource "scaleway_s2s_vpn_gateway" "main" { + name = "tf-test-vpn-gateway-connection" + gateway_type = "VGW-S" + private_network_id = scaleway_vpc_private_network.main.id + region = "fr-par" + zone = "fr-par-1" + } + + resource "scaleway_s2s_vpn_customer_gateway" "main" { + name = "tf-test-customer-gateway-connection" + ipv4_public = scaleway_instance_ip.customer_ip.address + asn = 65000 + region = "fr-par" + } + + resource "scaleway_s2s_vpn_routing_policy" "main" { + name = "tf-test-routing-policy-connection" + prefix_filter_in = ["10.0.1.0/24"] + prefix_filter_out = ["10.0.0.0/24"] + region = "fr-par" + } + + resource "scaleway_s2s_vpn_connection" "main" { + name = "tf-test-connection" + vpn_gateway_id = scaleway_s2s_vpn_gateway.main.id + customer_gateway_id = scaleway_s2s_vpn_customer_gateway.main.id + initiation_policy = "customer_gateway" + enable_route_propagation = true + region = "fr-par" + + bgp_config_ipv4 { + routing_policy_id = scaleway_s2s_vpn_routing_policy.main.id + private_ip = "169.254.0.1/30" + peer_private_ip = "169.254.0.2/30" + } + + ikev2_ciphers { + encryption = "aes256" + integrity = "sha256" + dh_group = "modp2048" + } + + esp_ciphers { + encryption = "aes256" + integrity = "sha256" + dh_group = "modp2048" + } + } + `, + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionExists(tt, "scaleway_s2s_vpn_connection.main"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "name", "tf-test-connection"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "initiation_policy", "customer_gateway"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "enable_route_propagation", "true"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_connection.main", "id"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_connection.main", "status"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_connection.main", "secret_id"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_connection.main", "secret_version"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "bgp_config_ipv4.0.private_ip", "169.254.0.1/30"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "bgp_config_ipv4.0.peer_private_ip", "169.254.0.2/30"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "ikev2_ciphers.0.encryption", "aes256"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "ikev2_ciphers.0.integrity", "sha256"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "ikev2_ciphers.0.dh_group", "modp2048"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "esp_ciphers.0.encryption", "aes256"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "esp_ciphers.0.integrity", "sha256"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_connection.main", "esp_ciphers.0.dh_group", "modp2048"), + ), + }, + }, + }) +} + +func testAccCheckConnectionExists(tt *acctest.TestTools, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("resource not found: %s", n) + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + connection, err := api.GetConnection(&s2s_vpn.GetConnectionRequest{ + ConnectionID: id, + Region: region, + }) + if err != nil { + return err + } + + if connection.Status.String() == "error" { + return errors.New("connection is in error state") + } + + return nil + } +} + +func testAccCheckConnectionDestroy(tt *acctest.TestTools) resource.TestCheckFunc { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "scaleway_s2s_vpn_connection" { + continue + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetConnection(&s2s_vpn.GetConnectionRequest{ + ConnectionID: id, + Region: region, + }) + if err == nil { + return fmt.Errorf("s2svpn connection (%s) still exists", rs.Primary.ID) + } + + if !httperrors.Is404(err) { + return err + } + } + + return nil + } +} diff --git a/internal/services/s2svpn/customer_gateway.go b/internal/services/s2svpn/customer_gateway.go new file mode 100644 index 0000000000..8652b73392 --- /dev/null +++ b/internal/services/s2svpn/customer_gateway.go @@ -0,0 +1,209 @@ +package s2svpn + +import ( + "context" + "net" + _ "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" +) + +func ResourceCustomerGateway() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceCustomerGatewayCreate, + ReadContext: ResourceCustomerGatewayRead, + UpdateContext: ResourceCustomerGatewayUpdate, + DeleteContext: ResourceCustomerGatewayDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The name of the customer gateway", + }, + "tags": { + Type: schema.TypeList, + Optional: true, + Description: "The list of tags to apply to the customer gateway", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ipv4_public": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The public IPv4 address of the customer gateway", + }, + "ipv6_public": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The public IPv6 address of the customer gateway", + }, + "asn": { + Type: schema.TypeInt, + Required: true, + Description: "The AS Number of the customer gateway", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the creation of the TLS stage", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the last update of the TLS stage", + }, + "region": regional.Schema(), + "project_id": account.ProjectIDSchema(), + "organization_id": { + Type: schema.TypeString, + Computed: true, + Description: "Organization ID of the Project", + }, + }, + } +} + +func ResourceCustomerGatewayCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, err := NewAPIWithRegion(d, m) + if err != nil { + return diag.FromErr(err) + } + + req := &s2s_vpn.CreateCustomerGatewayRequest{ + Region: region, + ProjectID: d.Get("project_id").(string), + Name: types.ExpandOrGenerateString(d.Get("name").(string), "connection"), + Tags: types.ExpandStrings(d.Get("tags")), + Asn: uint32(d.Get("asn").(int)), + } + + if d.Get("ipv4_public").(string) != "" { + req.IPv4Public = scw.IPPtr(net.ParseIP(d.Get("ipv4_public").(string))) + } + + if d.Get("ipv6_public").(string) != "" { + req.IPv6Public = scw.IPPtr(net.ParseIP(d.Get("ipv6_public").(string))) + } + + res, err := api.CreateCustomerGateway(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(regional.NewIDString(region, res.ID)) + + return ResourceCustomerGatewayRead(ctx, d, m) +} + +func ResourceCustomerGatewayRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + gateway, err := api.GetCustomerGateway(&s2s_vpn.GetCustomerGatewayRequest{ + GatewayID: id, + Region: region, + }, scw.WithContext(ctx)) + if err != nil { + if httperrors.Is404(err) { + d.SetId("") + + return nil + } + + return diag.FromErr(err) + } + + _ = d.Set("name", gateway.Name) + _ = d.Set("project_id", gateway.ProjectID) + _ = d.Set("organization_id", gateway.OrganizationID) + _ = d.Set("tags", gateway.Tags) + _ = d.Set("created_at", types.FlattenTime(gateway.CreatedAt)) + _ = d.Set("updated_at", types.FlattenTime(gateway.UpdatedAt)) + _ = d.Set("ipv4_public", types.FlattenIPPtr(gateway.PublicIPv4)) + _ = d.Set("ipv6_public", types.FlattenIPPtr(gateway.PublicIPv6)) + _ = d.Set("asn", int(gateway.Asn)) + + return nil +} + +func ResourceCustomerGatewayUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + req := &s2s_vpn.UpdateCustomerGatewayRequest{ + Region: region, + GatewayID: id, + } + + if d.HasChange("name") { + req.Name = types.ExpandUpdatedStringPtr(d.Get("name")) + hasChanged = true + } + + if d.HasChange("tags") { + req.Tags = types.ExpandUpdatedStringsPtr(d.Get("tags")) + hasChanged = true + } + + if d.HasChange("ipv4_public") { + req.IPv4Public = scw.IPPtr(net.ParseIP(d.Get("ipv4_public").(string))) + hasChanged = true + } + + if d.HasChange("ipv6_public") { + req.IPv6Public = scw.IPPtr(net.ParseIP(d.Get("ipv6_public").(string))) + hasChanged = true + } + + if d.HasChange("asn") { + req.Asn = types.ExpandUint32Ptr(d.Get("asn")) + hasChanged = true + } + + if hasChanged { + _, err = api.UpdateCustomerGateway(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + } + + return ResourceCustomerGatewayRead(ctx, d, m) +} + +func ResourceCustomerGatewayDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + err = api.DeleteCustomerGateway(&s2s_vpn.DeleteCustomerGatewayRequest{ + Region: region, + GatewayID: id, + }, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/s2svpn/customer_gateway_test.go b/internal/services/s2svpn/customer_gateway_test.go new file mode 100644 index 0000000000..d0967ecf62 --- /dev/null +++ b/internal/services/s2svpn/customer_gateway_test.go @@ -0,0 +1,98 @@ +package s2svpn_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/s2svpn" +) + +func TestAccCustomerGateway_Basic(t *testing.T) { + tt := acctest.NewTestTools(t) + defer tt.Cleanup() + + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: tt.ProviderFactories, + CheckDestroy: testAccCheckCustomerGatewayDestroy(tt), + Steps: []resource.TestStep{ + { + Config: ` + resource "scaleway_instance_ip" "main" {} + + resource "scaleway_s2s_vpn_customer_gateway" "main" { + name = "tf-test-customer-gateway" + ipv4_public = scaleway_instance_ip.main.address + asn = 65000 + region = "fr-par" + } + `, + Check: resource.ComposeTestCheckFunc( + testAccCheckCustomerGatewayExists(tt, "scaleway_s2s_vpn_customer_gateway.main"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_customer_gateway.main", "name", "tf-test-customer-gateway"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_customer_gateway.main", "asn", "65000"), + resource.TestCheckResourceAttrPair("scaleway_s2s_vpn_customer_gateway.main", "ipv4_public", "scaleway_instance_ip.main", "address"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_customer_gateway.main", "updated_at"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_customer_gateway.main", "created_at"), + ), + }, + }, + }) +} + +func testAccCheckCustomerGatewayExists(tt *acctest.TestTools, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("resource not found: %s", n) + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetCustomerGateway(&s2s_vpn.GetCustomerGatewayRequest{ + GatewayID: id, + Region: region, + }) + if err != nil { + return err + } + + return nil + } +} + +func testAccCheckCustomerGatewayDestroy(tt *acctest.TestTools) resource.TestCheckFunc { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "scaleway_s2s_vpn_customer_gateway" { + continue + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetCustomerGateway(&s2s_vpn.GetCustomerGatewayRequest{ + GatewayID: id, + Region: region, + }) + if err == nil { + return fmt.Errorf("customer gateway (%s) still exists", rs.Primary.ID) + } + + if !httperrors.Is404(err) { + return err + } + } + + return nil + } +} diff --git a/internal/services/s2svpn/helpers_s2svpn.go b/internal/services/s2svpn/helpers_s2svpn.go new file mode 100644 index 0000000000..889a9ff517 --- /dev/null +++ b/internal/services/s2svpn/helpers_s2svpn.go @@ -0,0 +1,33 @@ +package s2svpn + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + s2svpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/meta" +) + +// NewAPIWithRegion returns a new s2svpn API and the region for a Create request +func NewAPIWithRegion(d *schema.ResourceData, m any) (*s2svpn.API, scw.Region, error) { + s2svpnAPI := s2svpn.NewAPI(meta.ExtractScwClient(m)) + + region, err := meta.ExtractRegion(d, m) + if err != nil { + return nil, "", err + } + + return s2svpnAPI, region, nil +} + +// NewAPIWithRegionAndID returns a new s2svpn API with region and ID extracted from the state +func NewAPIWithRegionAndID(m any, regionalID string) (*s2svpn.API, scw.Region, string, error) { + s2svpnAPI := s2svpn.NewAPI(meta.ExtractScwClient(m)) + + region, ID, err := regional.ParseID(regionalID) + if err != nil { + return nil, "", "", err + } + + return s2svpnAPI, region, ID, nil +} diff --git a/internal/services/s2svpn/routing_policy.go b/internal/services/s2svpn/routing_policy.go new file mode 100644 index 0000000000..536fd3a8d0 --- /dev/null +++ b/internal/services/s2svpn/routing_policy.go @@ -0,0 +1,216 @@ +package s2svpn + +import ( + "context" + _ "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" +) + +func ResourceRoutingPolicy() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceRoutingPolicyCreate, + ReadContext: ResourceRoutingPolicyRead, + UpdateContext: ResourceRoutingPolicyUpdate, + DeleteContext: ResourceRoutingPolicyDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The name of the routing policy", + }, + "tags": { + Type: schema.TypeList, + Optional: true, + Description: "The list of tags to apply to the routing policy", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "is_ipv6": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: "IP prefixes version of the routing policy", + }, + "prefix_filter_in": { + Type: schema.TypeList, + Optional: true, + Description: "IP prefixes to accept from the peer (ranges of route announcements to accept)", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.IsCIDR, + }, + }, + "prefix_filter_out": { + Type: schema.TypeList, + Optional: true, + Description: "IP prefix filters to advertise to the peer (ranges of routes to advertise)", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.IsCIDR, + }, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the creation of the TLS stage", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the last update of the TLS stage", + }, + "region": regional.Schema(), + "project_id": account.ProjectIDSchema(), + "organization_id": { + Type: schema.TypeString, + Computed: true, + Description: "Organization ID of the Project", + }, + }, + } +} + +func ResourceRoutingPolicyCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, err := NewAPIWithRegion(d, m) + if err != nil { + return diag.FromErr(err) + } + + prefixFilterIn, err := expandPrefixFilters(d.Get("prefix_filter_in")) + if err != nil { + return diag.FromErr(err) + } + + prefixFilterOut, err := expandPrefixFilters(d.Get("prefix_filter_out")) + if err != nil { + return diag.FromErr(err) + } + + req := &s2s_vpn.CreateRoutingPolicyRequest{ + Region: region, + ProjectID: d.Get("project_id").(string), + Name: types.ExpandOrGenerateString(d.Get("name").(string), "connection"), + Tags: types.ExpandStrings(d.Get("tags")), + IsIPv6: d.Get("is_ipv6").(bool), + PrefixFilterIn: prefixFilterIn, + PrefixFilterOut: prefixFilterOut, + } + + res, err := api.CreateRoutingPolicy(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(regional.NewIDString(region, res.ID)) + + return ResourceRoutingPolicyRead(ctx, d, m) +} + +func ResourceRoutingPolicyRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + policy, err := api.GetRoutingPolicy(&s2s_vpn.GetRoutingPolicyRequest{ + RoutingPolicyID: id, + Region: region, + }, scw.WithContext(ctx)) + if err != nil { + if httperrors.Is404(err) { + d.SetId("") + + return nil + } + + return diag.FromErr(err) + } + + prefixFilterIn, err := FlattenPrefixFilters(policy.PrefixFilterIn) + if err != nil { + return diag.FromErr(err) + } + + prefixFilterOut, err := FlattenPrefixFilters(policy.PrefixFilterOut) + if err != nil { + return diag.FromErr(err) + } + + _ = d.Set("name", policy.Name) + _ = d.Set("region", policy.Region) + _ = d.Set("project_id", policy.ProjectID) + _ = d.Set("organization_id", policy.OrganizationID) + _ = d.Set("tags", policy.Tags) + _ = d.Set("created_at", types.FlattenTime(policy.CreatedAt)) + _ = d.Set("updated_at", types.FlattenTime(policy.UpdatedAt)) + _ = d.Set("is_ipv6", policy.IsIPv6) + _ = d.Set("prefix_filter_in", prefixFilterIn) + _ = d.Set("prefix_filter_out", prefixFilterOut) + + return nil +} + +func ResourceRoutingPolicyUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + req := &s2s_vpn.UpdateRoutingPolicyRequest{ + Region: region, + RoutingPolicyID: id, + } + + if d.HasChange("name") { + req.Name = types.ExpandUpdatedStringPtr(d.Get("name")) + hasChanged = true + } + + if d.HasChange("tags") { + req.Tags = types.ExpandUpdatedStringsPtr(d.Get("tags")) + hasChanged = true + } + + if hasChanged { + _, err = api.UpdateRoutingPolicy(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + } + + return ResourceRoutingPolicyRead(ctx, d, m) +} + +func ResourceRoutingPolicyDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + err = api.DeleteRoutingPolicy(&s2s_vpn.DeleteRoutingPolicyRequest{ + Region: region, + RoutingPolicyID: id, + }, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/s2svpn/routing_policy_test.go b/internal/services/s2svpn/routing_policy_test.go new file mode 100644 index 0000000000..351813ed61 --- /dev/null +++ b/internal/services/s2svpn/routing_policy_test.go @@ -0,0 +1,98 @@ +package s2svpn_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/s2svpn" +) + +func TestAccRoutingPolicy_Basic(t *testing.T) { + tt := acctest.NewTestTools(t) + defer tt.Cleanup() + + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: tt.ProviderFactories, + CheckDestroy: testAccCheckRoutingPolicyDestroy(tt), + Steps: []resource.TestStep{ + { + Config: ` + resource "scaleway_s2s_vpn_routing_policy" "main" { + name = "tf-test-routing-policy" + prefix_filter_in = ["10.0.1.0/24"] + prefix_filter_out = ["10.0.2.0/24"] + region = "fr-par" + } + `, + Check: resource.ComposeTestCheckFunc( + testAccCheckRoutingPolicyExists(tt, "scaleway_s2s_vpn_routing_policy.main"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_routing_policy.main", "name", "tf-test-routing-policy"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_routing_policy.main", "is_ipv6", "false"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_routing_policy.main", "region", "fr-par"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_routing_policy.main", "prefix_filter_in.#", "1"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_routing_policy.main", "prefix_filter_out.#", "1"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_routing_policy.main", "created_at"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_routing_policy.main", "updated_at"), + ), + }, + }, + }) +} + +func testAccCheckRoutingPolicyExists(tt *acctest.TestTools, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("resource not found: %s", n) + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetRoutingPolicy(&s2s_vpn.GetRoutingPolicyRequest{ + RoutingPolicyID: id, + Region: region, + }) + if err != nil { + return err + } + + return nil + } +} + +func testAccCheckRoutingPolicyDestroy(tt *acctest.TestTools) resource.TestCheckFunc { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "scaleway_s2s_vpn_routing_policy" { + continue + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetRoutingPolicy(&s2s_vpn.GetRoutingPolicyRequest{ + RoutingPolicyID: id, + Region: region, + }) + if err == nil { + return fmt.Errorf("routing policy (%s) still exists", rs.Primary.ID) + } + + if !httperrors.Is404(err) { + return err + } + } + + return nil + } +} diff --git a/internal/services/s2svpn/sweep_test.go b/internal/services/s2svpn/sweep_test.go new file mode 100644 index 0000000000..4cca056c76 --- /dev/null +++ b/internal/services/s2svpn/sweep_test.go @@ -0,0 +1,16 @@ +package s2svpn_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + s2svpntestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/s2svpn/testfuncs" +) + +func init() { + s2svpntestfuncs.AddTestSweepers() +} + +func TestMain(m *testing.M) { + resource.TestMain(m) +} diff --git a/internal/services/s2svpn/testdata/connection-basic.cassette.yaml b/internal/services/s2svpn/testdata/connection-basic.cassette.yaml new file mode 100644 index 0000000000..93602dc5d1 --- /dev/null +++ b/internal/services/s2svpn/testdata/connection-basic.cassette.yaml @@ -0,0 +1,2065 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 118 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"name":"tf-test-vpc-connection","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","tags":[],"enable_routing":false}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 409 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.734227Z","custom_routes_propagation_enabled":true,"id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f","is_default":false,"name":"tf-test-vpc-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_count":0,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","routing_enabled":true,"tags":[],"updated_at":"2025-12-10T16:24:52.734227Z"}' + headers: + Content-Length: + - "409" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:52 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 7349f4cc-e6e9-4b6e-bc12-ea35b492f70c + status: 200 OK + code: 200 + duration: 437.871375ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 193 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-routing-policy-connection","tags":[],"is_ipv6":false,"prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.0.0/24"]}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 398 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.773350Z","id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b","is_ipv6":false,"name":"tf-test-routing-policy-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.0.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-10T16:24:52.773350Z"}' + headers: + Content-Length: + - "398" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:52 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 72f43db7-d8d9-4e3b-b649-77c18e99b11e + status: 200 OK + code: 200 + duration: 456.777666ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs/fde76fe0-4e6d-4ece-bea0-a80e1966fb3f + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 409 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.734227Z","custom_routes_propagation_enabled":true,"id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f","is_default":false,"name":"tf-test-vpc-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_count":0,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","routing_enabled":true,"tags":[],"updated_at":"2025-12-10T16:24:52.734227Z"}' + headers: + Content-Length: + - "409" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:52 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 2223ed1f-bd39-4452-a287-0bd5e1a12950 + status: 200 OK + code: 200 + duration: 56.079041ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/8660f996-1d4f-4e3b-a6bd-56eaac12754b + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 398 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.773350Z","id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b","is_ipv6":false,"name":"tf-test-routing-policy-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.0.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-10T16:24:52.773350Z"}' + headers: + Content-Length: + - "398" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:52 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 24b13c63-f8d1-4c9f-8ae2-710fd9522edc + status: 200 OK + code: 200 + duration: 107.464041ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 50 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5"}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 365 + uncompressed: false + body: '{"ip":{"address":"51.15.138.130","id":"e12aad84-16c7-4012-905f-d90301f4e033","ipam_id":"e12aad84-16c7-4012-905f-d90301f4e033","organization":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix":null,"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","reverse":null,"server":null,"state":"detached","tags":[],"type":"routed_ipv4","zone":"fr-par-1"}}' + headers: + Content-Length: + - "365" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:52 GMT + Location: + - https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/e12aad84-16c7-4012-905f-d90301f4e033 + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 7ffeb843-5693-46a3-a722-f07cb6c7bdde + status: 201 Created + code: 201 + duration: 669.739666ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/e12aad84-16c7-4012-905f-d90301f4e033 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 365 + uncompressed: false + body: '{"ip":{"address":"51.15.138.130","id":"e12aad84-16c7-4012-905f-d90301f4e033","ipam_id":"e12aad84-16c7-4012-905f-d90301f4e033","organization":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix":null,"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","reverse":null,"server":null,"state":"detached","tags":[],"type":"routed_ipv4","zone":"fr-par-1"}}' + headers: + Content-Length: + - "365" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:53 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 9cd8d366-62c6-4094-a042-0899071fc520 + status: 200 OK + code: 200 + duration: 106.914458ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 150 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-customer-gateway-connection","tags":[],"ipv4_public":"51.15.138.130","asn":65000}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 337 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-10T16:24:53.226069Z","id":"226420ee-41a2-4b98-a978-116d6e4cecad","name":"tf-test-customer-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.138.130","tags":[],"updated_at":"2025-12-10T16:24:53.226069Z"}' + headers: + Content-Length: + - "337" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:53 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 5e4947cd-6961-45a6-9bee-85674c49194c + status: 200 OK + code: 200 + duration: 131.873333ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/226420ee-41a2-4b98-a978-116d6e4cecad + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 337 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-10T16:24:53.226069Z","id":"226420ee-41a2-4b98-a978-116d6e4cecad","name":"tf-test-customer-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.138.130","tags":[],"updated_at":"2025-12-10T16:24:53.226069Z"}' + headers: + Content-Length: + - "337" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:53 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 14bd48e5-2114-445a-b07c-b888268b26a5 + status: 200 OK + code: 200 + duration: 61.865625ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 208 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"name":"tf-pn-cocky-faraday","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","tags":[],"subnets":["10.0.0.0/24"],"vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f","default_route_propagation_enabled":false}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1062 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.899937Z","default_route_propagation_enabled":false,"dhcp_enabled":true,"id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","name":"tf-pn-cocky-faraday","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","subnets":[{"created_at":"2025-12-10T16:24:52.899937Z","id":"142933e7-95c3-40ca-a549-2225ca51da56","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"10.0.0.0/24","updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"},{"created_at":"2025-12-10T16:24:52.899937Z","id":"a27d4e29-8418-44ac-9532-79a5467c8513","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"fd46:78ab:30b8:46ff::/64","updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"}],"tags":[],"updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"}' + headers: + Content-Length: + - "1062" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:53 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 05b8c340-1ca0-4539-ac22-d2b4f569975e + status: 200 OK + code: 200 + duration: 620.536166ms + - id: 9 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks/d5209a7c-8a13-49d2-ab6c-64eba224280d + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1062 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.899937Z","default_route_propagation_enabled":false,"dhcp_enabled":true,"id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","name":"tf-pn-cocky-faraday","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","subnets":[{"created_at":"2025-12-10T16:24:52.899937Z","id":"142933e7-95c3-40ca-a549-2225ca51da56","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"10.0.0.0/24","updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"},{"created_at":"2025-12-10T16:24:52.899937Z","id":"a27d4e29-8418-44ac-9532-79a5467c8513","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"fd46:78ab:30b8:46ff::/64","updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"}],"tags":[],"updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"}' + headers: + Content-Length: + - "1062" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:53 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 70c79bf8-8097-4d1f-beee-533999f8a220 + status: 200 OK + code: 200 + duration: 58.837958ms + - id: 10 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 204 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-vpn-gateway-connection","tags":[],"gateway_type":"VGW-S","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","zone":"fr-par-1"}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"provisioning","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:24:54.394001Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:54 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - f08f37f4-42b4-4f56-bfa8-5bfba705d618 + status: 200 OK + code: 200 + duration: 1.084384584s + - id: 11 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"provisioning","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:24:54.394001Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:24:54 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 0296e49c-9d78-4f6d-be5b-847466ced3f1 + status: 200 OK + code: 200 + duration: 81.228084ms + - id: 12 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 756 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"active","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:34.779826Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "756" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:35 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 3b268dd7-acd5-4490-a5bf-28bccf6ced4f + status: 200 OK + code: 200 + duration: 51.539ms + - id: 13 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 756 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"active","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:34.779826Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "756" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:35 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - ac98198b-a810-458f-b61e-0215ec2e00e2 + status: 200 OK + code: 200 + duration: 32.422834ms + - id: 14 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 607 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-connection","tags":[],"is_ipv6":false,"initiation_policy":"customer_gateway","ikev2_ciphers":[{"encryption":"aes256","integrity":"sha256","dh_group":"modp2048"}],"esp_ciphers":[{"encryption":"aes256","integrity":"sha256","dh_group":"modp2048"}],"enable_route_propagation":true,"vpn_gateway_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","customer_gateway_id":"226420ee-41a2-4b98-a978-116d6e4cecad","bgp_config_ipv4":{"routing_policy_id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b","private_ip":"169.254.0.1/30","peer_private_ip":"169.254.0.2/30"}}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/connections + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1103 + uncompressed: false + body: '{"connection":{"bgp_session_ipv4":{"peer_private_ip":"169.254.0.2/30","private_ip":"169.254.0.1/30","routing_policy_id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b"},"bgp_status_ipv4":"down","bgp_status_ipv6":"disabled","created_at":"2025-12-10T16:25:35.253496Z","customer_gateway_id":"226420ee-41a2-4b98-a978-116d6e4cecad","esp_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"id":"14fb4d03-1fdb-4d0e-ae70-f1c15805d663","ikev2_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"initiation_policy":"customer_gateway","is_ipv6":false,"name":"tf-test-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","route_propagation_enabled":true,"secret_id":"bfac5f2c-89d3-4b31-ac71-e301b340cf8c","secret_revision":1,"status":"down","tags":[],"tunnel_status":"down","tunnel_status_ipv4":"unknown_tunnel_status","tunnel_status_ipv6":"unknown_tunnel_status","updated_at":"2025-12-10T16:25:35.253496Z","vpn_gateway_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb"},"pre_shared_key":""}' + headers: + Content-Length: + - "1103" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:35 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - d5d3de22-6b72-4b3c-b91d-03b85cc50066 + status: 200 OK + code: 200 + duration: 742.222292ms + - id: 15 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/connections/14fb4d03-1fdb-4d0e-ae70-f1c15805d663 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1068 + uncompressed: false + body: '{"bgp_session_ipv4":{"peer_private_ip":"169.254.0.2/30","private_ip":"169.254.0.1/30","routing_policy_id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b"},"bgp_status_ipv4":"down","bgp_status_ipv6":"disabled","created_at":"2025-12-10T16:25:35.253496Z","customer_gateway_id":"226420ee-41a2-4b98-a978-116d6e4cecad","esp_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"id":"14fb4d03-1fdb-4d0e-ae70-f1c15805d663","ikev2_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"initiation_policy":"customer_gateway","is_ipv6":false,"name":"tf-test-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","route_propagation_enabled":true,"secret_id":"bfac5f2c-89d3-4b31-ac71-e301b340cf8c","secret_revision":1,"status":"down","tags":[],"tunnel_status":"down","tunnel_status_ipv4":"unknown_tunnel_status","tunnel_status_ipv6":"unknown_tunnel_status","updated_at":"2025-12-10T16:25:35.253496Z","vpn_gateway_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb"}' + headers: + Content-Length: + - "1068" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:35 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - c1abd256-a230-4efd-b23e-bc7c853f5dfb + status: 200 OK + code: 200 + duration: 64.607667ms + - id: 16 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/connections/14fb4d03-1fdb-4d0e-ae70-f1c15805d663 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1068 + uncompressed: false + body: '{"bgp_session_ipv4":{"peer_private_ip":"169.254.0.2/30","private_ip":"169.254.0.1/30","routing_policy_id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b"},"bgp_status_ipv4":"down","bgp_status_ipv6":"disabled","created_at":"2025-12-10T16:25:35.253496Z","customer_gateway_id":"226420ee-41a2-4b98-a978-116d6e4cecad","esp_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"id":"14fb4d03-1fdb-4d0e-ae70-f1c15805d663","ikev2_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"initiation_policy":"customer_gateway","is_ipv6":false,"name":"tf-test-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","route_propagation_enabled":true,"secret_id":"bfac5f2c-89d3-4b31-ac71-e301b340cf8c","secret_revision":1,"status":"down","tags":[],"tunnel_status":"down","tunnel_status_ipv4":"unknown_tunnel_status","tunnel_status_ipv6":"unknown_tunnel_status","updated_at":"2025-12-10T16:25:35.253496Z","vpn_gateway_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb"}' + headers: + Content-Length: + - "1068" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 5026310e-b3a7-47b2-9949-31f791005af4 + status: 200 OK + code: 200 + duration: 22.382ms + - id: 17 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs/fde76fe0-4e6d-4ece-bea0-a80e1966fb3f + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 409 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.734227Z","custom_routes_propagation_enabled":true,"id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f","is_default":false,"name":"tf-test-vpc-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_count":1,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","routing_enabled":true,"tags":[],"updated_at":"2025-12-10T16:24:52.734227Z"}' + headers: + Content-Length: + - "409" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - ece9998f-dfc4-4dd5-bcdf-45fa2eec1ad1 + status: 200 OK + code: 200 + duration: 23.123875ms + - id: 18 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/8660f996-1d4f-4e3b-a6bd-56eaac12754b + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 398 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.773350Z","id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b","is_ipv6":false,"name":"tf-test-routing-policy-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.0.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-10T16:24:52.773350Z"}' + headers: + Content-Length: + - "398" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 465cd3f1-2cfb-47a1-84fc-bd7df606319b + status: 200 OK + code: 200 + duration: 69.883666ms + - id: 19 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/e12aad84-16c7-4012-905f-d90301f4e033 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 365 + uncompressed: false + body: '{"ip":{"address":"51.15.138.130","id":"e12aad84-16c7-4012-905f-d90301f4e033","ipam_id":"e12aad84-16c7-4012-905f-d90301f4e033","organization":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix":null,"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","reverse":null,"server":null,"state":"detached","tags":[],"type":"routed_ipv4","zone":"fr-par-1"}}' + headers: + Content-Length: + - "365" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 2576a02d-c111-4739-8e59-35eec3230c66 + status: 200 OK + code: 200 + duration: 81.889334ms + - id: 20 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks/d5209a7c-8a13-49d2-ab6c-64eba224280d + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1062 + uncompressed: false + body: '{"created_at":"2025-12-10T16:24:52.899937Z","default_route_propagation_enabled":false,"dhcp_enabled":true,"id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","name":"tf-pn-cocky-faraday","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","subnets":[{"created_at":"2025-12-10T16:24:52.899937Z","id":"142933e7-95c3-40ca-a549-2225ca51da56","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"10.0.0.0/24","updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"},{"created_at":"2025-12-10T16:24:52.899937Z","id":"a27d4e29-8418-44ac-9532-79a5467c8513","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"fd46:78ab:30b8:46ff::/64","updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"}],"tags":[],"updated_at":"2025-12-10T16:24:52.899937Z","vpc_id":"fde76fe0-4e6d-4ece-bea0-a80e1966fb3f"}' + headers: + Content-Length: + - "1062" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 3a4c824c-9bc4-4c00-9452-a7b9127f6019 + status: 200 OK + code: 200 + duration: 58.529625ms + - id: 21 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 761 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"configuring","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:35.816218Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "761" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 56b9ebd7-b006-4743-98cb-a8ab6cb74629 + status: 200 OK + code: 200 + duration: 27.432708ms + - id: 22 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/226420ee-41a2-4b98-a978-116d6e4cecad + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 337 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-10T16:24:53.226069Z","id":"226420ee-41a2-4b98-a978-116d6e4cecad","name":"tf-test-customer-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.138.130","tags":[],"updated_at":"2025-12-10T16:24:53.226069Z"}' + headers: + Content-Length: + - "337" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:36 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 068ccb98-173f-4168-af19-a89a53ab6018 + status: 200 OK + code: 200 + duration: 46.7455ms + - id: 23 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 756 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"active","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:38.052217Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "756" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:41 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 654de6bc-75a4-4f2c-b647-2a1abae18b50 + status: 200 OK + code: 200 + duration: 33.988959ms + - id: 24 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/connections/14fb4d03-1fdb-4d0e-ae70-f1c15805d663 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1068 + uncompressed: false + body: '{"bgp_session_ipv4":{"peer_private_ip":"169.254.0.2/30","private_ip":"169.254.0.1/30","routing_policy_id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b"},"bgp_status_ipv4":"down","bgp_status_ipv6":"disabled","created_at":"2025-12-10T16:25:35.253496Z","customer_gateway_id":"226420ee-41a2-4b98-a978-116d6e4cecad","esp_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"id":"14fb4d03-1fdb-4d0e-ae70-f1c15805d663","ikev2_ciphers":[{"dh_group":"modp2048","encryption":"aes256","integrity":"sha256"}],"initiation_policy":"customer_gateway","is_ipv6":false,"name":"tf-test-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","route_propagation_enabled":true,"secret_id":"bfac5f2c-89d3-4b31-ac71-e301b340cf8c","secret_revision":1,"status":"down","tags":[],"tunnel_status":"down","tunnel_status_ipv4":"unknown_tunnel_status","tunnel_status_ipv6":"unknown_tunnel_status","updated_at":"2025-12-10T16:25:35.253496Z","vpn_gateway_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb"}' + headers: + Content-Length: + - "1068" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:41 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 0f2145d9-9efe-45f9-be6e-ccdfaa711b04 + status: 200 OK + code: 200 + duration: 46.804542ms + - id: 25 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/connections/14fb4d03-1fdb-4d0e-ae70-f1c15805d663 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:42 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 205a452e-4357-41f8-975b-c5273ea80587 + status: 204 No Content + code: 204 + duration: 381.760167ms + - id: 26 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 761 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"configuring","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:41.736033Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "761" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:42 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 0d9c4f8d-098b-43d1-89fc-eb96f306313c + status: 200 OK + code: 200 + duration: 44.303875ms + - id: 27 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/8660f996-1d4f-4e3b-a6bd-56eaac12754b + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:42 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 971c6896-fd4a-4280-aa49-c5eb30b3da30 + status: 204 No Content + code: 204 + duration: 87.689458ms + - id: 28 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/226420ee-41a2-4b98-a978-116d6e4cecad + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:42 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - a15774f4-7302-4052-9018-516611b39e16 + status: 204 No Content + code: 204 + duration: 93.47725ms + - id: 29 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/e12aad84-16c7-4012-905f-d90301f4e033 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:42 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - ccee8c6a-54e1-4f9e-afdf-349a6d13a6ad + status: 204 No Content + code: 204 + duration: 232.659917ms + - id: 30 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 756 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"active","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:46.801902Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "756" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:47 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - ad7a25b9-041a-4c2f-b378-ddcb2e3828ac + status: 200 OK + code: 200 + duration: 53.664792ms + - id: 31 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 764 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:47.209505Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "764" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:47 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 79af18a4-5dad-453c-9cf3-a48d82730e96 + status: 200 OK + code: 200 + duration: 123.639625ms + - id: 32 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 764 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:47.209505Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "764" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:47 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 3b076d82-061f-47b9-9bfa-a0f1ac89805b + status: 200 OK + code: 200 + duration: 51.314292ms + - id: 33 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 764 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:47.209505Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "764" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:52 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 175cdf25-c66f-43e7-9ac5-3c0ccc5a83d3 + status: 200 OK + code: 200 + duration: 50.635458ms + - id: 34 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 764 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-10T16:24:54.394001Z","gateway_type":"VGW-S","id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","ipam_private_ipv4_id":"9ad67f4b-2d51-4e36-a997-a09faedcac83","ipam_private_ipv6_id":"2631532e-f06a-4359-978a-2ed1c6e13aea","name":"tf-test-vpn-gateway-connection","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"d5209a7c-8a13-49d2-ab6c-64eba224280d","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"cffff5ae-5961-4aff-a96f-754c04c42799","ipam_ipv6_id":"1c543163-a778-4613-9062-3e1d4b4c963c"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.158.74.241/32","public_ipv6=2001:bc8:711:16fa::/64"],"updated_at":"2025-12-10T16:25:47.209505Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "764" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:25:57 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - e5f5436f-6f7d-43e2-b9e1-747f3f134ee0 + status: 200 OK + code: 200 + duration: 74.686542ms + - id: 35 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 132 + uncompressed: false + body: '{"message":"resource is not found","resource":"vpn_gateway","resource_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","type":"not_found"}' + headers: + Content-Length: + - "132" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:02 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - d62827b0-78e2-4436-a7c9-61ea4ca2e0e3 + status: 404 Not Found + code: 404 + duration: 30.770458ms + - id: 36 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks/d5209a7c-8a13-49d2-ab6c-64eba224280d + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:03 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - aace660e-ff8d-46a0-90c8-00b1d327945b + status: 204 No Content + code: 204 + duration: 1.353062958s + - id: 37 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs/fde76fe0-4e6d-4ece-bea0-a80e1966fb3f + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - fa4b2efd-5d39-4417-8d4c-4bd6a688ece0 + status: 204 No Content + code: 204 + duration: 266.060833ms + - id: 38 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/connections/14fb4d03-1fdb-4d0e-ae70-f1c15805d663 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 131 + uncompressed: false + body: '{"message":"resource is not found","resource":"connection","resource_id":"14fb4d03-1fdb-4d0e-ae70-f1c15805d663","type":"not_found"}' + headers: + Content-Length: + - "131" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 7845802b-2ee8-48fa-9546-853e71529b4d + status: 404 Not Found + code: 404 + duration: 32.860875ms + - id: 39 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/b70c9398-fed3-44a3-b937-e9e2c86305cb + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 132 + uncompressed: false + body: '{"message":"resource is not found","resource":"vpn_gateway","resource_id":"b70c9398-fed3-44a3-b937-e9e2c86305cb","type":"not_found"}' + headers: + Content-Length: + - "132" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - e1fd5d8d-5fff-45b1-b1c4-cf0ee7908f32 + status: 404 Not Found + code: 404 + duration: 23.362667ms + - id: 40 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/226420ee-41a2-4b98-a978-116d6e4cecad + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 137 + uncompressed: false + body: '{"message":"resource is not found","resource":"customer_gateway","resource_id":"226420ee-41a2-4b98-a978-116d6e4cecad","type":"not_found"}' + headers: + Content-Length: + - "137" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 2915b630-c368-4423-8c3a-b159d82cb08c + status: 404 Not Found + code: 404 + duration: 24.840792ms + - id: 41 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/8660f996-1d4f-4e3b-a6bd-56eaac12754b + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 135 + uncompressed: false + body: '{"message":"resource is not found","resource":"routing_policy","resource_id":"8660f996-1d4f-4e3b-a6bd-56eaac12754b","type":"not_found"}' + headers: + Content-Length: + - "135" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Wed, 10 Dec 2025 16:26:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge03) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 93aefa20-c0de-4702-9cea-c9607ff5f971 + status: 404 Not Found + code: 404 + duration: 21.184792ms diff --git a/internal/services/s2svpn/testdata/customer-gateway-basic.cassette.yaml b/internal/services/s2svpn/testdata/customer-gateway-basic.cassette.yaml new file mode 100644 index 0000000000..7645823b74 --- /dev/null +++ b/internal/services/s2svpn/testdata/customer-gateway-basic.cassette.yaml @@ -0,0 +1,495 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 50 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5"}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 365 + uncompressed: false + body: '{"ip":{"address":"51.15.128.186","id":"947f8278-8cf9-4902-8ada-9d694107291e","ipam_id":"947f8278-8cf9-4902-8ada-9d694107291e","organization":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix":null,"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","reverse":null,"server":null,"state":"detached","tags":[],"type":"routed_ipv4","zone":"fr-par-1"}}' + headers: + Content-Length: + - "365" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:27 GMT + Location: + - https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/947f8278-8cf9-4902-8ada-9d694107291e + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 9086d55d-eff1-434b-b2c5-32eedfea7aa7 + status: 201 Created + code: 201 + duration: 419.233375ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/947f8278-8cf9-4902-8ada-9d694107291e + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 365 + uncompressed: false + body: '{"ip":{"address":"51.15.128.186","id":"947f8278-8cf9-4902-8ada-9d694107291e","ipam_id":"947f8278-8cf9-4902-8ada-9d694107291e","organization":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix":null,"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","reverse":null,"server":null,"state":"detached","tags":[],"type":"routed_ipv4","zone":"fr-par-1"}}' + headers: + Content-Length: + - "365" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:27 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - fdd9ebba-442e-420c-a8a7-0b18709e342a + status: 200 OK + code: 200 + duration: 112.301875ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 139 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-customer-gateway","tags":[],"ipv4_public":"51.15.128.186","asn":65000}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 334 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-05T09:36:27.669033Z","id":"9ccfe336-9077-4f3d-90b8-cc401a049c16","name":"tf-test-customer-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.128.186","tags":[],"updated_at":"2025-12-05T09:36:27.669033Z"}' + headers: + Content-Length: + - "334" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:27 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 0e7bf26a-ef0d-481d-a6c0-ae6e146e7354 + status: 200 OK + code: 200 + duration: 170.017584ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/9ccfe336-9077-4f3d-90b8-cc401a049c16 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 334 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-05T09:36:27.669033Z","id":"9ccfe336-9077-4f3d-90b8-cc401a049c16","name":"tf-test-customer-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.128.186","tags":[],"updated_at":"2025-12-05T09:36:27.669033Z"}' + headers: + Content-Length: + - "334" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:27 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - b9205b2d-68d3-4475-ada0-e3b72af1ec41 + status: 200 OK + code: 200 + duration: 90.819375ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/9ccfe336-9077-4f3d-90b8-cc401a049c16 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 334 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-05T09:36:27.669033Z","id":"9ccfe336-9077-4f3d-90b8-cc401a049c16","name":"tf-test-customer-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.128.186","tags":[],"updated_at":"2025-12-05T09:36:27.669033Z"}' + headers: + Content-Length: + - "334" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:27 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 7dac648b-01b6-4878-a89f-d009d4d5188d + status: 200 OK + code: 200 + duration: 94.136042ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/947f8278-8cf9-4902-8ada-9d694107291e + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 365 + uncompressed: false + body: '{"ip":{"address":"51.15.128.186","id":"947f8278-8cf9-4902-8ada-9d694107291e","ipam_id":"947f8278-8cf9-4902-8ada-9d694107291e","organization":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix":null,"project":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","reverse":null,"server":null,"state":"detached","tags":[],"type":"routed_ipv4","zone":"fr-par-1"}}' + headers: + Content-Length: + - "365" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:28 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 25b699df-c5f5-4a87-9bb6-307b9f0b6b65 + status: 200 OK + code: 200 + duration: 99.399333ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/9ccfe336-9077-4f3d-90b8-cc401a049c16 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 334 + uncompressed: false + body: '{"asn":65000,"created_at":"2025-12-05T09:36:27.669033Z","id":"9ccfe336-9077-4f3d-90b8-cc401a049c16","name":"tf-test-customer-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_ipv4":"51.15.128.186","tags":[],"updated_at":"2025-12-05T09:36:27.669033Z"}' + headers: + Content-Length: + - "334" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:28 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - d1a53954-d774-420e-a276-36cde1bfb176 + status: 200 OK + code: 200 + duration: 72.784458ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/9ccfe336-9077-4f3d-90b8-cc401a049c16 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:28 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - fc5c0bd1-9545-411b-9765-6dd06eb504e6 + status: 204 No Content + code: 204 + duration: 54.810208ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/instance/v1/zones/fr-par-1/ips/947f8278-8cf9-4902-8ada-9d694107291e + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:28 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - b58831c7-466a-438f-8be7-bb83e9bfaec6 + status: 204 No Content + code: 204 + duration: 193.136334ms + - id: 9 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/customer-gateways/9ccfe336-9077-4f3d-90b8-cc401a049c16 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 137 + uncompressed: false + body: '{"message":"resource is not found","resource":"customer_gateway","resource_id":"9ccfe336-9077-4f3d-90b8-cc401a049c16","type":"not_found"}' + headers: + Content-Length: + - "137" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:36:28 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 12b0a259-1964-4b53-b92c-100c23e92e33 + status: 404 Not Found + code: 404 + duration: 20.354042ms diff --git a/internal/services/s2svpn/testdata/routing-policy-basic.cassette.yaml b/internal/services/s2svpn/testdata/routing-policy-basic.cassette.yaml new file mode 100644 index 0000000000..faa993b4bb --- /dev/null +++ b/internal/services/s2svpn/testdata/routing-policy-basic.cassette.yaml @@ -0,0 +1,297 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 182 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-routing-policy","tags":[],"is_ipv6":false,"prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.2.0/24"]}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 397 + uncompressed: false + body: '{"created_at":"2025-12-05T09:32:03.778567Z","id":"b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac","is_ipv6":false,"name":"tf-test-routing-policy","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.2.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-05T09:32:03.778567Z"}' + headers: + Content-Length: + - "397" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:32:03 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 4b9cb6b4-ee3e-430e-b053-9a3623957a30 + status: 200 OK + code: 200 + duration: 225.773ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 397 + uncompressed: false + body: '{"created_at":"2025-12-05T09:32:03.778567Z","id":"b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac","is_ipv6":false,"name":"tf-test-routing-policy","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.2.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-05T09:32:03.778567Z"}' + headers: + Content-Length: + - "397" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:32:03 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - d842b5c8-ccf7-4381-9a51-d993f5a7a2cd + status: 200 OK + code: 200 + duration: 81.742333ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 397 + uncompressed: false + body: '{"created_at":"2025-12-05T09:32:03.778567Z","id":"b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac","is_ipv6":false,"name":"tf-test-routing-policy","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.2.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-05T09:32:03.778567Z"}' + headers: + Content-Length: + - "397" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:32:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 4b29ef45-7f81-4721-a5dd-d1134ca1ef68 + status: 200 OK + code: 200 + duration: 77.270917ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 397 + uncompressed: false + body: '{"created_at":"2025-12-05T09:32:03.778567Z","id":"b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac","is_ipv6":false,"name":"tf-test-routing-policy","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","prefix_filter_in":["10.0.1.0/24"],"prefix_filter_out":["10.0.2.0/24"],"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","tags":[],"updated_at":"2025-12-05T09:32:03.778567Z"}' + headers: + Content-Length: + - "397" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:32:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 0be6a96c-6687-41ac-97ac-cbef8c532c1f + status: 200 OK + code: 200 + duration: 60.706958ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:32:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 771462de-9f00-405e-ae68-ed4c75a312d9 + status: 204 No Content + code: 204 + duration: 83.256125ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/routing-policies/b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 135 + uncompressed: false + body: '{"message":"resource is not found","resource":"routing_policy","resource_id":"b0832ffa-3b4c-4a7e-a224-5c84fc7aa4ac","type":"not_found"}' + headers: + Content-Length: + - "135" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:32:04 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 51964991-82df-4691-81fd-37e6e48eadcf + status: 404 Not Found + code: 404 + duration: 19.848375ms diff --git a/internal/services/s2svpn/testdata/vpn-gateway-basic.cassette.yaml b/internal/services/s2svpn/testdata/vpn-gateway-basic.cassette.yaml new file mode 100644 index 0000000000..5b530912fd --- /dev/null +++ b/internal/services/s2svpn/testdata/vpn-gateway-basic.cassette.yaml @@ -0,0 +1,1034 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 119 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"name":"tf-test-vpc-vpn-gateway","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","tags":[],"enable_routing":false}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 421 + uncompressed: false + body: '{"created_at":"2025-12-05T09:29:56.526830Z","custom_routes_propagation_enabled":true,"id":"ba3039bd-bb43-438b-a465-d14dfedb6a26","is_default":false,"name":"tf-test-vpc-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_count":0,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","routing_enabled":true,"tags":[],"updated_at":"2025-12-05T09:29:56.526830Z"}' + headers: + Content-Length: + - "421" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:29:56 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 9f2f561e-1ad7-440e-ba7b-ba2931941f71 + status: 200 OK + code: 200 + duration: 513.67475ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs/ba3039bd-bb43-438b-a465-d14dfedb6a26 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 421 + uncompressed: false + body: '{"created_at":"2025-12-05T09:29:56.526830Z","custom_routes_propagation_enabled":true,"id":"ba3039bd-bb43-438b-a465-d14dfedb6a26","is_default":false,"name":"tf-test-vpc-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_count":0,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","routing_enabled":true,"tags":[],"updated_at":"2025-12-05T09:29:56.526830Z"}' + headers: + Content-Length: + - "421" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:29:56 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 633d0475-bd52-49b1-9429-ebd7d071101a + status: 200 OK + code: 200 + duration: 60.206208ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 206 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"name":"tf-pn-hungry-nash","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","tags":[],"subnets":["10.0.0.0/24"],"vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26","default_route_propagation_enabled":false}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1084 + uncompressed: false + body: '{"created_at":"2025-12-05T09:29:56.676437Z","default_route_propagation_enabled":false,"dhcp_enabled":true,"id":"7896655c-1037-43ac-8713-1096c2b6461e","name":"tf-pn-hungry-nash","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","subnets":[{"created_at":"2025-12-05T09:29:56.676437Z","id":"06d12828-cb7e-4904-9983-3c4a80a7ea1b","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"10.0.0.0/24","updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"},{"created_at":"2025-12-05T09:29:56.676437Z","id":"6ec6dc79-b7e0-4f3a-8e72-a902df3b378c","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"fd46:78ab:30b8:efe3::/64","updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"}],"tags":[],"updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"}' + headers: + Content-Length: + - "1084" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:29:57 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 1ee0353f-bb16-4a1e-88e5-bc2001594621 + status: 200 OK + code: 200 + duration: 583.41ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks/7896655c-1037-43ac-8713-1096c2b6461e + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1084 + uncompressed: false + body: '{"created_at":"2025-12-05T09:29:56.676437Z","default_route_propagation_enabled":false,"dhcp_enabled":true,"id":"7896655c-1037-43ac-8713-1096c2b6461e","name":"tf-pn-hungry-nash","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","subnets":[{"created_at":"2025-12-05T09:29:56.676437Z","id":"06d12828-cb7e-4904-9983-3c4a80a7ea1b","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"10.0.0.0/24","updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"},{"created_at":"2025-12-05T09:29:56.676437Z","id":"6ec6dc79-b7e0-4f3a-8e72-a902df3b378c","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"fd46:78ab:30b8:efe3::/64","updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"}],"tags":[],"updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"}' + headers: + Content-Length: + - "1084" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:29:57 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - c55ec826-4f70-4f4c-a113-a00289b8c181 + status: 200 OK + code: 200 + duration: 25.33525ms + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 193 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","name":"tf-test-vpn-gateway","tags":[],"gateway_type":"VGW-S","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","zone":"fr-par-1"}' + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 768 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"provisioning","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:29:58.114379Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "768" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:29:58 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - fea12348-31d1-4a0d-9cb6-89bef9837083 + status: 200 OK + code: 200 + duration: 1.083256375s + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 768 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"provisioning","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:29:58.114379Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "768" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:29:58 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 43716bfb-9b1e-4d2d-a29a-02c630f217dc + status: 200 OK + code: 200 + duration: 48.683459ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"active","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:38.059158Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:38 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - cd7be51f-af5b-4e52-bd13-10a810c2f415 + status: 200 OK + code: 200 + duration: 35.112709ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"active","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:38.059158Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:38 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 98dda72f-ad3f-48c7-bf3d-529e2cbff0c7 + status: 200 OK + code: 200 + duration: 46.0635ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"active","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:38.059158Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:38 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 30f8e9cc-0164-49fb-bec7-e18997fe0dab + status: 200 OK + code: 200 + duration: 37.255209ms + - id: 9 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs/ba3039bd-bb43-438b-a465-d14dfedb6a26 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 421 + uncompressed: false + body: '{"created_at":"2025-12-05T09:29:56.526830Z","custom_routes_propagation_enabled":true,"id":"ba3039bd-bb43-438b-a465-d14dfedb6a26","is_default":false,"name":"tf-test-vpc-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_count":1,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","routing_enabled":true,"tags":[],"updated_at":"2025-12-05T09:29:56.526830Z"}' + headers: + Content-Length: + - "421" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:39 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - d4288ef7-d4cc-49b2-ad15-b8b09a658e2c + status: 200 OK + code: 200 + duration: 90.931ms + - id: 10 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks/7896655c-1037-43ac-8713-1096c2b6461e + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 1084 + uncompressed: false + body: '{"created_at":"2025-12-05T09:29:56.676437Z","default_route_propagation_enabled":false,"dhcp_enabled":true,"id":"7896655c-1037-43ac-8713-1096c2b6461e","name":"tf-pn-hungry-nash","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","region":"fr-par","subnets":[{"created_at":"2025-12-05T09:29:56.676437Z","id":"06d12828-cb7e-4904-9983-3c4a80a7ea1b","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"10.0.0.0/24","updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"},{"created_at":"2025-12-05T09:29:56.676437Z","id":"6ec6dc79-b7e0-4f3a-8e72-a902df3b378c","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","subnet":"fd46:78ab:30b8:efe3::/64","updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"}],"tags":[],"updated_at":"2025-12-05T09:29:56.676437Z","vpc_id":"ba3039bd-bb43-438b-a465-d14dfedb6a26"}' + headers: + Content-Length: + - "1084" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:39 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 78ecda19-e03a-4401-b7cb-e2b20576c48e + status: 200 OK + code: 200 + duration: 61.483958ms + - id: 11 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"active","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:38.059158Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:39 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - e6548a9c-cfb8-4863-be55-a6e45e349032 + status: 200 OK + code: 200 + duration: 45.290542ms + - id: 12 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 762 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"active","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:38.059158Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "762" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:39 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 66dd7ef8-a3e5-4d82-827f-359724480dcc + status: 200 OK + code: 200 + duration: 33.427542ms + - id: 13 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 770 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:39.570333Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "770" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:39 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - af9dce6e-0099-4aa1-8b85-58d58095742d + status: 200 OK + code: 200 + duration: 78.167292ms + - id: 14 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 770 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:39.570333Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "770" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:39 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 86139514-735f-42f9-9ddf-98e3ddce033f + status: 200 OK + code: 200 + duration: 38.764167ms + - id: 15 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 770 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:39.570333Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "770" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:44 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - fc6b8cfd-b789-4282-a5c6-c3bdc01865d1 + status: 200 OK + code: 200 + duration: 57.721042ms + - id: 16 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 770 + uncompressed: false + body: '{"asn":12876,"created_at":"2025-12-05T09:29:58.114379Z","gateway_type":"VGW-S","id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","ipam_private_ipv4_id":"344f9fb7-84a4-41a4-b4e5-2aee2cbe3e83","ipam_private_ipv6_id":"8195b154-3576-4af1-a415-2b34e6277ff2","name":"tf-test-vpn-gateway","organization_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","private_network_id":"7896655c-1037-43ac-8713-1096c2b6461e","project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","public_config":{"ipam_ipv4_id":"5b88f3e6-7e26-4353-99b4-1ac427116e94","ipam_ipv6_id":"67549cd5-f754-4fca-9497-851d2cec08b2"},"region":"fr-par","status":"deprovisioning","tags":["public_ipv4=51.15.129.108/32","public_ipv6=2001:bc8:711:121f::/64"],"updated_at":"2025-12-05T09:30:39.570333Z","zone":"fr-par-1"}' + headers: + Content-Length: + - "770" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:49 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - e2c7c891-a144-4edc-b899-335710ba94ee + status: 200 OK + code: 200 + duration: 36.26625ms + - id: 17 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 132 + uncompressed: false + body: '{"message":"resource is not found","resource":"vpn_gateway","resource_id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","type":"not_found"}' + headers: + Content-Length: + - "132" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:54 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 68ba1f12-70b2-45bb-b29b-9a74790d205b + status: 404 Not Found + code: 404 + duration: 22.712417ms + - id: 18 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/private-networks/7896655c-1037-43ac-8713-1096c2b6461e + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:56 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - fd267d28-03b4-4ab8-86cd-a19f48082d32 + status: 204 No Content + code: 204 + duration: 1.288793834s + - id: 19 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/vpc/v2/regions/fr-par/vpcs/ba3039bd-bb43-438b-a465-d14dfedb6a26 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:56 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - 1ac7c92e-afe6-4dad-a77f-558638b05a27 + status: 204 No Content + code: 204 + duration: 155.034417ms + - id: 20 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.scaleway.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + User-Agent: + - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.25.3; darwin; arm64) terraform-provider/develop terraform/terraform-tests + url: https://api.scaleway.com/s2s-vpn/v1alpha1/regions/fr-par/vpn-gateways/2723a992-24a5-4fd5-99b3-b991dcd5c74a + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 132 + uncompressed: false + body: '{"message":"resource is not found","resource":"vpn_gateway","resource_id":"2723a992-24a5-4fd5-99b3-b991dcd5c74a","type":"not_found"}' + headers: + Content-Length: + - "132" + Content-Security-Policy: + - default-src 'none'; frame-ancestors 'none' + Content-Type: + - application/json + Date: + - Fri, 05 Dec 2025 09:30:56 GMT + Server: + - Scaleway API Gateway (fr-par-3;edge02) + Strict-Transport-Security: + - max-age=63072000 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + X-Request-Id: + - e27261b4-4e48-4178-83f8-ee7dac5b8f19 + status: 404 Not Found + code: 404 + duration: 22.5845ms diff --git a/internal/services/s2svpn/testfuncs/sweep.go b/internal/services/s2svpn/testfuncs/sweep.go new file mode 100644 index 0000000000..c080e2a82c --- /dev/null +++ b/internal/services/s2svpn/testfuncs/sweep.go @@ -0,0 +1,145 @@ +package s2svpntestfuncs + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/logging" +) + +func AddTestSweepers() { + resource.AddTestSweepers("scaleway_s2s_vpn_connection", &resource.Sweeper{ + Name: "scaleway_s2s_vpn_connection", + F: testSweepConnection, + Dependencies: []string{"scaleway_s2s_vpn_gateway", "scaleway_s2s_vpn_customer_gateway"}, + }) + + resource.AddTestSweepers("scaleway_s2s_vpn_gateway", &resource.Sweeper{ + Name: "scaleway_s2s_vpn_gateway", + F: testSweepVPNGateway, + Dependencies: []string{"scaleway_s2s_vpn_connection"}, + }) + + resource.AddTestSweepers("scaleway_s2s_vpn_customer_gateway", &resource.Sweeper{ + Name: "scaleway_s2s_vpn_customer_gateway", + F: testSweepCustomerGateway, + Dependencies: []string{"scaleway_s2s_vpn_connection"}, + }) + + resource.AddTestSweepers("scaleway_s2s_vpn_routing_policy", &resource.Sweeper{ + Name: "scaleway_s2s_vpn_routing_policy", + F: testSweepRoutingPolicy, + Dependencies: []string{"scaleway_s2s_vpn_connection"}, + }) +} + +func testSweepConnection(_ string) error { + return acctest.SweepRegions(scw.AllRegions, func(scwClient *scw.Client, region scw.Region) error { + s2svpnAPI := s2s_vpn.NewAPI(scwClient) + + logging.L.Debugf("sweeper: destroying the s2s vpn connection in (%s)", region) + + listConnections, err := s2svpnAPI.ListConnections(&s2s_vpn.ListConnectionsRequest{ + Region: region, + }, scw.WithAllPages()) + if err != nil { + return fmt.Errorf("error listing s2s vpn connections in (%s) in sweeper: %w", region, err) + } + + for _, connection := range listConnections.Connections { + err := s2svpnAPI.DeleteConnection(&s2s_vpn.DeleteConnectionRequest{ + Region: region, + ConnectionID: connection.ID, + }) + if err != nil { + return fmt.Errorf("error deleting s2s vpn connection in sweeper: %w", err) + } + } + + return nil + }) +} + +func testSweepVPNGateway(_ string) error { + return acctest.SweepRegions(scw.AllRegions, func(scwClient *scw.Client, region scw.Region) error { + s2svpnAPI := s2s_vpn.NewAPI(scwClient) + + logging.L.Debugf("sweeper: destroying the s2s vpn gateway in (%s)", region) + + listGateways, err := s2svpnAPI.ListVpnGateways(&s2s_vpn.ListVpnGatewaysRequest{ + Region: region, + }, scw.WithAllPages()) + if err != nil { + return fmt.Errorf("error listing s2s vpn gateways in (%s) in sweeper: %w", region, err) + } + + for _, gateway := range listGateways.Gateways { + _, err := s2svpnAPI.DeleteVpnGateway(&s2s_vpn.DeleteVpnGatewayRequest{ + Region: region, + GatewayID: gateway.ID, + }) + if err != nil { + return fmt.Errorf("error deleting s2s vpn gateway in sweeper: %w", err) + } + } + + return nil + }) +} + +func testSweepCustomerGateway(_ string) error { + return acctest.SweepRegions(scw.AllRegions, func(scwClient *scw.Client, region scw.Region) error { + s2svpnAPI := s2s_vpn.NewAPI(scwClient) + + logging.L.Debugf("sweeper: destroying the s2s vpn customer gateway in (%s)", region) + + listGateways, err := s2svpnAPI.ListCustomerGateways(&s2s_vpn.ListCustomerGatewaysRequest{ + Region: region, + }, scw.WithAllPages()) + if err != nil { + return fmt.Errorf("error listing s2s vpn customer gateways in (%s) in sweeper: %w", region, err) + } + + for _, gateway := range listGateways.Gateways { + err := s2svpnAPI.DeleteCustomerGateway(&s2s_vpn.DeleteCustomerGatewayRequest{ + Region: region, + GatewayID: gateway.ID, + }) + if err != nil { + return fmt.Errorf("error deleting s2s vpn customer gateway in sweeper: %w", err) + } + } + + return nil + }) +} + +func testSweepRoutingPolicy(_ string) error { + return acctest.SweepRegions(scw.AllRegions, func(scwClient *scw.Client, region scw.Region) error { + s2svpnAPI := s2s_vpn.NewAPI(scwClient) + + logging.L.Debugf("sweeper: destroying the s2s vpn routing policy in (%s)", region) + + listPolicies, err := s2svpnAPI.ListRoutingPolicies(&s2s_vpn.ListRoutingPoliciesRequest{ + Region: region, + }, scw.WithAllPages()) + if err != nil { + return fmt.Errorf("error listing s2s vpn routing policies in (%s) in sweeper: %w", region, err) + } + + for _, policy := range listPolicies.RoutingPolicies { + err := s2svpnAPI.DeleteRoutingPolicy(&s2s_vpn.DeleteRoutingPolicyRequest{ + Region: region, + RoutingPolicyID: policy.ID, + }) + if err != nil { + return fmt.Errorf("error deleting s2s vpn routing policy in sweeper: %w", err) + } + } + + return nil + }) +} diff --git a/internal/services/s2svpn/types.go b/internal/services/s2svpn/types.go new file mode 100644 index 0000000000..8ac1a7ff1c --- /dev/null +++ b/internal/services/s2svpn/types.go @@ -0,0 +1,180 @@ +package s2svpn + +import ( + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "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" +) + +func expandVPNGatewayPublicConfig(raw any) *s2s_vpn.CreateVpnGatewayRequestPublicConfig { + if raw == nil || len(raw.([]any)) != 1 { + return nil + } + + rawMap := raw.([]any)[0].(map[string]any) + + return &s2s_vpn.CreateVpnGatewayRequestPublicConfig{ + IpamIPv4ID: types.ExpandStringPtr(locality.ExpandID(rawMap["ipam_ipv4_id"].(string))), + IpamIPv6ID: types.ExpandStringPtr(locality.ExpandID(rawMap["ipam_ipv6_id"].(string))), + } +} + +func expandConnectionRequestBgpConfig(raw any) (config *s2s_vpn.CreateConnectionRequestBgpConfig, err error) { + if raw == nil || len(raw.([]any)) != 1 { + return nil, nil + } + + rawMap := raw.([]any)[0].(map[string]any) + + privateIPNet, err := types.ExpandIPNet(rawMap["private_ip"].(string)) + if err != nil { + return nil, err + } + + peerPrivateIPNet, err := types.ExpandIPNet(rawMap["peer_private_ip"].(string)) + if err != nil { + return nil, err + } + + return &s2s_vpn.CreateConnectionRequestBgpConfig{ + RoutingPolicyID: locality.ExpandID(rawMap["routing_policy_id"].(string)), + PrivateIP: &privateIPNet, + PeerPrivateIP: &peerPrivateIPNet, + }, nil +} + +func expandPrefixFilters(raw any) ([]scw.IPNet, error) { + if raw == nil { + return nil, nil + } + + rawList, ok := raw.([]any) + if !ok || len(rawList) == 0 { + return nil, nil + } + + prefixes := make([]scw.IPNet, 0, len(rawList)) + for _, v := range rawList { + ipNet, err := types.ExpandIPNet(v.(string)) + if err != nil { + return nil, err + } + + prefixes = append(prefixes, ipNet) + } + + return prefixes, nil +} + +func expandConnectionCiphers(raw any) []*s2s_vpn.ConnectionCipher { + if raw == nil { + return nil + } + + rawList := raw.([]any) + + res := make([]*s2s_vpn.ConnectionCipher, 0, len(rawList)) + for _, item := range rawList { + m, ok := item.(map[string]any) + if !ok { + continue + } + + c := &s2s_vpn.ConnectionCipher{ + Encryption: s2s_vpn.ConnectionEncryption(m["encryption"].(string)), + } + + if v, ok := m["integrity"]; ok { + val := s2s_vpn.ConnectionIntegrity(v.(string)) + c.Integrity = &val + } + + if v, ok := m["dh_group"]; ok { + val := s2s_vpn.ConnectionDhGroup(v.(string)) + c.DhGroup = &val + } + + res = append(res, c) + } + + return res +} + +func flattenVPNGatewayPublicConfig(region scw.Region, config *s2s_vpn.VpnGatewayPublicConfig) any { + if config == nil { + return nil + } + + return []map[string]any{ + { + "ipam_ipv4_id": regional.NewIDString(region, types.FlattenStringPtr(config.IpamIPv4ID).(string)), + "ipam_ipv6_id": regional.NewIDString(region, types.FlattenStringPtr(config.IpamIPv6ID).(string)), + }, + } +} + +func flattenBGPSession(region scw.Region, session *s2s_vpn.BgpSession) (any, error) { + if session == nil { + return nil, nil + } + + privateIP, err := types.FlattenIPNet(session.PrivateIP) + if err != nil { + return nil, err + } + + peerPrivateIP, err := types.FlattenIPNet(session.PeerPrivateIP) + if err != nil { + return nil, err + } + + return []map[string]any{ + { + "routing_policy_id": regional.NewIDString(region, session.RoutingPolicyID), + "private_ip": privateIP, + "peer_private_ip": peerPrivateIP, + }, + }, nil +} + +func FlattenPrefixFilters(prefixes []scw.IPNet) ([]string, error) { + res := make([]string, 0, len(prefixes)) + + for _, p := range prefixes { + flattened, err := types.FlattenIPNet(p) + if err != nil { + return nil, err + } + + res = append(res, flattened) + } + + return res, nil +} + +func flattenConnectionCiphers(ciphers []*s2s_vpn.ConnectionCipher) []any { + if len(ciphers) == 0 { + return nil + } + + res := make([]any, 0, len(ciphers)) + + for _, c := range ciphers { + m := map[string]any{ + "encryption": c.Encryption.String(), + } + if c.Integrity != nil { + m["integrity"] = c.Integrity.String() + } + + if c.DhGroup != nil { + m["dh_group"] = c.DhGroup.String() + } + + res = append(res, m) + } + + return res +} diff --git a/internal/services/s2svpn/vpn_gateway.go b/internal/services/s2svpn/vpn_gateway.go new file mode 100644 index 0000000000..483313dd49 --- /dev/null +++ b/internal/services/s2svpn/vpn_gateway.go @@ -0,0 +1,260 @@ +package s2svpn + +import ( + "context" + _ "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + s2svpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" +) + +func ResourceVPNGateway() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceVPNGatewayCreate, + ReadContext: ResourceVPNGatewayRead, + UpdateContext: ResourceVPNGatewayUpdate, + DeleteContext: ResourceVPNGatewayDelete, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(defaulVPNGatewayTimeout), + Read: schema.DefaultTimeout(defaulVPNGatewayTimeout), + Update: schema.DefaultTimeout(defaulVPNGatewayTimeout), + Delete: schema.DefaultTimeout(defaulVPNGatewayTimeout), + Default: schema.DefaultTimeout(defaulVPNGatewayTimeout), + }, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The name of the VPN gateway", + }, + "tags": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "The list of tags to apply to the VPN gateway", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "gateway_type": { + Type: schema.TypeString, + Required: true, + Description: "The VPN gateway type (commercial offer type)", + }, + "public_config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: "The public endpoint configuration of the VPN gateway", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ipam_ipv4_id": { + Type: schema.TypeString, + Description: " The ID of the IPAM IPv4 address to use as the public IP for the VPN gateway", + Optional: true, + }, + "ipam_ipv6_id": { + Type: schema.TypeString, + Description: " The ID of the IPAM IPv6 address to use as the public IP for the VPN gateway", + Optional: true, + }, + }, + }, + }, + "private_network_id": { + Type: schema.TypeString, + Required: true, + Description: "The ID of the Private Network to attach to the VPN gateway", + }, + "ipam_private_ipv4_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The ID of the IPAM private IPv4 address to attach to the VPN gateway", + }, + "ipam_private_ipv6_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: "The ID of the IPAM private IPv6 address to attach to the VPN gateway", + }, + "asn": { + Type: schema.TypeInt, + Computed: true, + Description: "The AS Number of the vpn gateway", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the VPN gateway", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the creation of the VPN gateway", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The date and time of the last update of the VPN gateway", + }, + "zone": zonal.OptionalSchema(), + "region": regional.Schema(), + "project_id": account.ProjectIDSchema(), + "organization_id": { + Type: schema.TypeString, + Computed: true, + Description: "Organization ID of the Project", + }, + }, + } +} + +func ResourceVPNGatewayCreate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, err := NewAPIWithRegion(d, m) + if err != nil { + return diag.FromErr(err) + } + + zone := scw.Zone(d.Get("zone").(string)) + + req := &s2svpn.CreateVpnGatewayRequest{ + Region: region, + ProjectID: d.Get("project_id").(string), + Name: types.ExpandOrGenerateString(d.Get("name").(string), "connection"), + Tags: types.ExpandStrings(d.Get("tags")), + GatewayType: d.Get("gateway_type").(string), + PrivateNetworkID: regional.ExpandID(d.Get("private_network_id").(string)).ID, + IpamPrivateIPv4ID: types.ExpandStringPtr(d.Get("ipam_private_ipv4_id").(string)), + IpamPrivateIPv6ID: types.ExpandStringPtr(d.Get("ipam_private_ipv6_id").(string)), + Zone: &zone, + PublicConfig: expandVPNGatewayPublicConfig(d.Get("public_config")), + } + + res, err := api.CreateVpnGateway(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + _, err = waitForVPNGateway(ctx, api, region, res.ID, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(regional.NewIDString(region, res.ID)) + + return ResourceVPNGatewayRead(ctx, d, m) +} + +func ResourceVPNGatewayRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + gateway, err := waitForVPNGateway(ctx, api, region, id, d.Timeout(schema.TimeoutRead)) + if err != nil { + if httperrors.Is404(err) { + d.SetId("") + + return nil + } + + return diag.FromErr(err) + } + + _ = d.Set("name", gateway.Name) + _ = d.Set("region", gateway.Region) + _ = d.Set("project_id", gateway.ProjectID) + _ = d.Set("organization_id", gateway.OrganizationID) + _ = d.Set("tags", gateway.Tags) + _ = d.Set("created_at", types.FlattenTime(gateway.CreatedAt)) + _ = d.Set("updated_at", types.FlattenTime(gateway.UpdatedAt)) + _ = d.Set("asn", int(gateway.Asn)) + _ = d.Set("status", gateway.Status.String()) + _ = d.Set("gateway_type", gateway.GatewayType) + _ = d.Set("private_network_id", regional.NewIDString(region, gateway.PrivateNetworkID)) + _ = d.Set("ipam_private_ipv4_id", regional.NewIDString(region, gateway.IpamPrivateIPv4ID)) + _ = d.Set("ipam_private_ipv6_id", regional.NewIDString(region, gateway.IpamPrivateIPv6ID)) + _ = d.Set("zone", gateway.Zone) + _ = d.Set("public_config", flattenVPNGatewayPublicConfig(region, gateway.PublicConfig)) + + return nil +} + +func ResourceVPNGatewayUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + hasChanged := false + + req := &s2svpn.UpdateVpnGatewayRequest{ + Region: region, + GatewayID: id, + } + + if d.HasChange("name") { + req.Name = types.ExpandUpdatedStringPtr(d.Get("name")) + hasChanged = true + } + + if d.HasChange("tags") { + req.Tags = types.ExpandUpdatedStringsPtr(d.Get("tags")) + hasChanged = true + } + + if hasChanged { + _, err = api.UpdateVpnGateway(req, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + } + + _, err = waitForVPNGateway(ctx, api, region, id, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return diag.FromErr(err) + } + + return ResourceVPNGatewayRead(ctx, d, m) +} + +func ResourceVPNGatewayDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics { + api, region, id, err := NewAPIWithRegionAndID(m, d.Id()) + if err != nil { + return diag.FromErr(err) + } + + _, err = waitForVPNGateway(ctx, api, region, id, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return diag.FromErr(err) + } + + _, err = api.DeleteVpnGateway(&s2svpn.DeleteVpnGatewayRequest{ + Region: region, + GatewayID: id, + }, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + _, err = waitForVPNGateway(ctx, api, region, id, d.Timeout(schema.TimeoutDelete)) + if err != nil && !httperrors.Is404(err) { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/s2svpn/vpn_gateway_test.go b/internal/services/s2svpn/vpn_gateway_test.go new file mode 100644 index 0000000000..f1934b6d1d --- /dev/null +++ b/internal/services/s2svpn/vpn_gateway_test.go @@ -0,0 +1,114 @@ +package s2svpn_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/s2svpn" +) + +func TestAccVPNGateway_Basic(t *testing.T) { + tt := acctest.NewTestTools(t) + defer tt.Cleanup() + + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: tt.ProviderFactories, + CheckDestroy: testAccCheckVPNGatewayDestroy(tt), + Steps: []resource.TestStep{ + { + Config: ` + resource "scaleway_vpc" "main" { + name = "tf-test-vpc-vpn-gateway" + } + + resource "scaleway_vpc_private_network" "main" { + vpc_id = scaleway_vpc.main.id + ipv4_subnet { + subnet = "10.0.0.0/24" + } + } + + resource "scaleway_s2s_vpn_gateway" "main" { + name = "tf-test-vpn-gateway" + gateway_type = "VGW-S" + private_network_id = scaleway_vpc_private_network.main.id + region = "fr-par" + zone = "fr-par-1" + } + `, + Check: resource.ComposeTestCheckFunc( + testAccCheckVPNGatewayExists(tt, "scaleway_s2s_vpn_gateway.main"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_gateway.main", "name", "tf-test-vpn-gateway"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_gateway.main", "gateway_type", "VGW-S"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_gateway.main", "region", "fr-par"), + resource.TestCheckResourceAttr("scaleway_s2s_vpn_gateway.main", "zone", "fr-par-1"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "asn"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "status"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "public_config.#"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "ipam_private_ipv4_id"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "ipam_private_ipv6_id"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "created_at"), + resource.TestCheckResourceAttrSet("scaleway_s2s_vpn_gateway.main", "updated_at"), + ), + }, + }, + }) +} + +func testAccCheckVPNGatewayExists(tt *acctest.TestTools, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("resource not found: %s", n) + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetVpnGateway(&s2s_vpn.GetVpnGatewayRequest{ + GatewayID: id, + Region: region, + }) + if err != nil { + return err + } + + return nil + } +} + +func testAccCheckVPNGatewayDestroy(tt *acctest.TestTools) resource.TestCheckFunc { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "scaleway_s2s_vpn_gateway" { + continue + } + + api, region, id, err := s2svpn.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID) + if err != nil { + return err + } + + _, err = api.GetVpnGateway(&s2s_vpn.GetVpnGatewayRequest{ + GatewayID: id, + Region: region, + }) + if err == nil { + return fmt.Errorf("VPN gateway (%s) still exists", rs.Primary.ID) + } + + if !httperrors.Is404(err) { + return err + } + } + + return nil + } +} diff --git a/internal/services/s2svpn/waiters.go b/internal/services/s2svpn/waiters.go new file mode 100644 index 0000000000..1190445a68 --- /dev/null +++ b/internal/services/s2svpn/waiters.go @@ -0,0 +1,31 @@ +package s2svpn + +import ( + "context" + "time" + + s2s_vpn "github.com/scaleway/scaleway-sdk-go/api/s2s_vpn/v1alpha1" + "github.com/scaleway/scaleway-sdk-go/scw" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/transport" +) + +const ( + defaulVPNGatewayTimeout = 5 * time.Minute + defaultVPNGatewayRetryInterval = 5 * time.Second +) + +func waitForVPNGateway(ctx context.Context, api *s2s_vpn.API, region scw.Region, vpngwID string, timeout time.Duration) (*s2s_vpn.VpnGateway, error) { + retryInterval := defaultVPNGatewayRetryInterval + if transport.DefaultWaitRetryInterval != nil { + retryInterval = *transport.DefaultWaitRetryInterval + } + + server, err := api.WaitForVpnGateway(&s2s_vpn.WaitForVpnGatewayRequest{ + GatewayID: vpngwID, + Region: region, + Timeout: scw.TimeDurationPtr(timeout), + RetryInterval: &retryInterval, + }, scw.WithContext(ctx)) + + return server, err +} diff --git a/provider/sdkv2.go b/provider/sdkv2.go index 66b2cc9307..4ee2dab697 100644 --- a/provider/sdkv2.go +++ b/provider/sdkv2.go @@ -43,6 +43,7 @@ import ( "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/rdb" "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/redis" "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/registry" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/s2svpn" "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/scwconfig" "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/sdb" "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/secret" @@ -238,6 +239,10 @@ func SDKProvider(config *Config) plugin.ProviderFunc { "scaleway_rdb_snapshot": rdb.ResourceSnapshot(), "scaleway_redis_cluster": redis.ResourceCluster(), "scaleway_registry_namespace": registry.ResourceNamespace(), + "scaleway_s2s_vpn_gateway": s2svpn.ResourceVPNGateway(), + "scaleway_s2s_vpn_customer_gateway": s2svpn.ResourceCustomerGateway(), + "scaleway_s2s_vpn_connection": s2svpn.ResourceConnection(), + "scaleway_s2s_vpn_routing_policy": s2svpn.ResourceRoutingPolicy(), "scaleway_sdb_sql_database": sdb.ResourceDatabase(), "scaleway_secret": secret.ResourceSecret(), "scaleway_secret_version": secret.ResourceVersion(), diff --git a/templates/resources/s2s_vpn_connection.md.tmpl b/templates/resources/s2s_vpn_connection.md.tmpl new file mode 100644 index 0000000000..c7f9e92f90 --- /dev/null +++ b/templates/resources/s2s_vpn_connection.md.tmpl @@ -0,0 +1,163 @@ +{{- /*gotype: github.com/hashicorp/terraform-plugin-docs/internal/provider.ResourceTemplateType */ -}} +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_connection" +--- + +# Resource: scaleway_s2s_vpn_connection + +Creates and manages Scaleway Site-to-Site VPN Connections. +A connection links a Scaleway VPN Gateway to a Customer Gateway and establishes an IPSec tunnel with BGP routing. + +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic Connection + +```terraform +resource "scaleway_vpc" "vpc" { + name = "my-vpc" +} + +resource "scaleway_vpc_private_network" "pn" { + name = "my-private-network" + vpc_id = scaleway_vpc.vpc.id + ipv4_subnet { + subnet = "10.0.1.0/24" + } +} + +resource "scaleway_s2s_vpn_gateway" "gateway" { + name = "my-vpn-gateway" + gateway_type = "VGW-S" + private_network_id = scaleway_vpc_private_network.pn.id +} + +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = "203.0.113.1" + asn = 65000 +} + +resource "scaleway_s2s_vpn_routing_policy" "policy" { + name = "my-routing-policy" + prefix_filter_in = ["10.0.2.0/24"] + prefix_filter_out = ["10.0.1.0/24"] +} + +resource "scaleway_s2s_vpn_connection" "main" { + name = "my-vpn-connection" + vpn_gateway_id = scaleway_s2s_vpn_gateway.gateway.id + customer_gateway_id = scaleway_s2s_vpn_customer_gateway.customer_gw.id + initiation_policy = "customer_gateway" + enable_route_propagation = true + + bgp_config_ipv4 { + routing_policy_id = scaleway_s2s_vpn_routing_policy.policy.id + private_ip = "169.254.0.1/30" + peer_private_ip = "169.254.0.2/30" + } + + ikev2_ciphers { + encryption = "aes256" + integrity = "sha256" + dh_group = "modp2048" + } + + esp_ciphers { + encryption = "aes256" + integrity = "sha256" + dh_group = "modp2048" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `vpn_gateway_id` - (Required) The ID of the VPN gateway to attach to the connection. +- `customer_gateway_id` - (Required) The ID of the customer gateway to attach to the connection. +- `initiation_policy` - (Optional) Defines who initiates the IPSec tunnel. +- `enable_route_propagation` - (Optional) Defines whether route propagation is enabled or not. +- `bgp_config_ipv4` - (Optional) BGP configuration for IPv4. See [BGP Config](#bgp-config) below. +- `bgp_config_ipv6` - (Optional) BGP configuration for IPv6. See [BGP Config](#bgp-config) below. +- `ikev2_ciphers` - (Optional) IKEv2 cipher configuration for Phase 1 (tunnel establishment). See [Cipher Config](#cipher-config) below. +- `esp_ciphers` - (Optional) ESP cipher configuration for Phase 2 (data encryption). See [Cipher Config](#cipher-config) below. +- `name` - (Optional) The name of the connection. +- `tags` - (Optional) The list of tags to apply to the connection. +- `is_ipv6` - (Optional) Defines IP version of the IPSec Tunnel. Defaults to `false` (IPv4). +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the connection should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the connection is associated with. + +### BGP Config + +The `bgp_config_ipv4` and `bgp_config_ipv6` blocks support: + +- `routing_policy_id` - (Required) The ID of the routing policy to use for BGP route filtering. +- `private_ip` - (Optional) The BGP peer IP on Scaleway side (within the IPSec tunnel), in CIDR notation (e.g., `169.254.0.1/30`). If not provided, Scaleway will assign it automatically. +- `peer_private_ip` - (Optional) The BGP peer IP on customer side (within the IPSec tunnel), in CIDR notation (e.g., `169.254.0.2/30`). If not provided, Scaleway will assign it automatically. + +### Cipher Config + +The `ikev2_ciphers` and `esp_ciphers` blocks support: + +- `encryption` - (Required) The encryption algorithm. +- `integrity` - (Optional) The integrity/hash algorithm. +- `dh_group` - (Optional) The Diffie-Hellman group. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the connection. +- `status` - The status of the connection. +- `tunnel_status` - The status of the IPSec tunnel. +- `bgp_status_ipv4` - The status of the BGP IPv4 session. +- `bgp_status_ipv6` - The status of the BGP IPv6 session. +- `bgp_session_ipv4` - The BGP IPv4 session information. See [BGP Session](#bgp-session) below. +- `bgp_session_ipv6` - The BGP IPv6 session information. See [BGP Session](#bgp-session) below. +- `secret_id` - The ID of the secret containing the pre-shared key (PSK) for the connection. +- `secret_version` - The version of the secret containing the PSK. +- `route_propagation_enabled` - Whether route propagation is enabled. +- `created_at` - The date and time of the creation of the connection (RFC 3339 format). +- `updated_at` - The date and time of the last update of the connection (RFC 3339 format). +- `organization_id` - The Organization ID the connection is associated with. + +### BGP Session + +The `bgp_session_ipv4` and `bgp_session_ipv6` blocks contain (read-only): + +- `routing_policy_id` - The routing policy ID used for this BGP session. +- `private_ip` - The BGP peer IP on Scaleway side (within the tunnel). +- `peer_private_ip` - The BGP peer IP on customer side (within the tunnel). + +~> **Important:** Connections' 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` + +~> **Important:** The pre-shared key (PSK) is auto-generated when the connection is created and stored in Scaleway Secret Manager. You can retrieve it using the `scaleway_secret_version` datasource or via the API. + +## Retrieving the Pre-Shared Key (PSK) + +The PSK is stored in Secret Manager and can be retrieved using: + +```terraform +data "scaleway_secret_version" "s2s_psk" { + secret_id = scaleway_s2s_vpn_connection.main.secret_id + revision = tostring(scaleway_s2s_vpn_connection.main.secret_version) +} + +# The PSK is available as base64-encoded data +output "psk" { + value = data.scaleway_secret_version.s2s_psk.data + sensitive = true +} +``` + +## Import + +Connections can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_connection.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/templates/resources/s2s_vpn_customer_gateway.md.tmpl b/templates/resources/s2s_vpn_customer_gateway.md.tmpl new file mode 100644 index 0000000000..40e897923e --- /dev/null +++ b/templates/resources/s2s_vpn_customer_gateway.md.tmpl @@ -0,0 +1,85 @@ +{{- /*gotype: github.com/hashicorp/terraform-plugin-docs/internal/provider.ResourceTemplateType */ -}} +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_customer_gateway" +--- + +# Resource: scaleway_s2s_vpn_customer_gateway + +Creates and manages Scaleway Site-to-Site VPN Customer Gateways. +A customer gateway represents your external VPN endpoint (e.g., a firewall, router, or VPN appliance). + +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic + +```terraform +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = "203.0.113.1" + asn = 65000 +} +``` + +### With IPv6 + +```terraform +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = "203.0.113.1" + ipv6_public = "2001:db8::1" + asn = 65000 +} +``` + +### Using Instance Public IP + +```terraform +resource "scaleway_instance_ip" "vpn_endpoint_ip" {} + +resource "scaleway_instance_server" "vpn_endpoint" { + name = "vpn-endpoint" + type = "DEV1-S" + image = "ubuntu_jammy" + ip_ids = [scaleway_instance_ip.vpn_endpoint_ip.id] +} + +resource "scaleway_s2s_vpn_customer_gateway" "customer_gw" { + name = "my-customer-gateway" + ipv4_public = scaleway_instance_ip.vpn_endpoint_ip.address + asn = 65000 +} +``` + +## Argument Reference + +The following arguments are supported: + +- `asn` - (Required) The AS Number of the customer gateway. Must be different from Scaleway's ASN (12876). For testing, you can use a private ASN (64512-65535). +- `ipv4_public` - (Optional) The public IPv4 address of the customer gateway (your VPN endpoint). +- `ipv6_public` - (Optional) The public IPv6 address of the customer gateway (your VPN endpoint). +- `name` - (Optional) The name of the customer gateway. If not provided, it will be randomly generated. +- `tags` - (Optional) The list of tags to apply to the customer gateway. +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the customer gateway should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the customer gateway is associated with. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the customer gateway. +- `created_at` - The date and time of the creation of the customer gateway (RFC 3339 format). +- `updated_at` - The date and time of the last update of the customer gateway (RFC 3339 format). +- `organization_id` - The Organization ID the customer gateway is associated with. + +~> **Important:** Customer Gateways' 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` + +## Import + +Customer Gateways can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_customer_gateway.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/templates/resources/s2s_vpn_gateway.md.tmpl b/templates/resources/s2s_vpn_gateway.md.tmpl new file mode 100644 index 0000000000..aca4638701 --- /dev/null +++ b/templates/resources/s2s_vpn_gateway.md.tmpl @@ -0,0 +1,78 @@ +{{- /*gotype: github.com/hashicorp/terraform-plugin-docs/internal/provider.ResourceTemplateType */ -}} +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_gateway" +--- + +# Resource: scaleway_s2s_vpn_gateway + +Creates and manages Scaleway Site-to-Site VPN Gateways. +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic + +```terraform +resource "scaleway_vpc" "vpc" { + name = "my-vpc" +} + +resource "scaleway_vpc_private_network" "pn" { + name = "my-private-network" + vpc_id = scaleway_vpc.vpc.id + ipv4_subnet { + subnet = "10.0.1.0/24" + } +} + +resource "scaleway_s2s_vpn_gateway" "gateway" { + name = "my-vpn-gateway" + gateway_type = "VGW-S" + private_network_id = scaleway_vpc_private_network.pn.id +} +``` + +## Argument Reference + +The following arguments are supported: + +- `gateway_type` - (Required) The VPN gateway type (commercial offer type). +- `private_network_id` - (Required) The ID of the Private Network to attach to the VPN gateway. +- `name` - (Optional) The name of the VPN gateway. If not provided, it will be randomly generated. +- `tags` - (Optional) The list of tags to apply to the VPN gateway. +- `public_config` - (Optional) The public endpoint configuration of the VPN gateway. See [Public Config](#public-config) below. +- `ipam_private_ipv4_id` - (Optional) The ID of the IPAM private IPv4 address to attach to the VPN gateway. +- `ipam_private_ipv6_id` - (Optional) The ID of the IPAM private IPv6 address to attach to the VPN gateway. +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the VPN gateway should be created. +- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the VPN gateway should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the VPN gateway is associated with. + +### Public Config + +The `public_config` block supports: + +- `ipam_ipv4_id` - (Optional) The ID of the IPAM IPv4 address to use as the public IP for the VPN gateway. +- `ipam_ipv6_id` - (Optional) The ID of the IPAM IPv6 address to use as the public IP for the VPN gateway. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the VPN gateway. +- `asn` - The AS Number of the VPN gateway (typically 12876 for Scaleway). +- `status` - The status of the VPN gateway. +- `public_config` - The public endpoint configuration, including the assigned public IPs. +- `created_at` - The date and time of the creation of the VPN gateway (RFC 3339 format). +- `updated_at` - The date and time of the last update of the VPN gateway (RFC 3339 format). +- `organization_id` - The Organization ID the VPN gateway is associated with. + +~> **Important:** VPN Gateways' 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` + +## Import + +VPN Gateways can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_gateway.main fr-par/11111111-1111-1111-1111-111111111111 +``` diff --git a/templates/resources/s2s_vpn_routing_policy.md.tmpl b/templates/resources/s2s_vpn_routing_policy.md.tmpl new file mode 100644 index 0000000000..8f1caeb1d4 --- /dev/null +++ b/templates/resources/s2s_vpn_routing_policy.md.tmpl @@ -0,0 +1,65 @@ +{{- /*gotype: github.com/hashicorp/terraform-plugin-docs/internal/provider.ResourceTemplateType */ -}} +--- +subcategory: "S2S VPN" +page_title: "Scaleway: scaleway_s2s_vpn_routing_policy" +--- + +# Resource: scaleway_s2s_vpn_routing_policy + +Creates and manages Scaleway Site-to-Site VPN Routing Policies. +A routing policy defines which routes are accepted from and advertised to the peer gateway via BGP. + +For more information, see [the main documentation](https://www.scaleway.com/en/docs/site-to-site-vpn/reference-content/understanding-s2svpn/). + +## Example Usage + +### Basic + +```terraform +resource "scaleway_s2s_vpn_routing_policy" "policy" { + name = "my-routing-policy" + prefix_filter_in = ["10.0.2.0/24"] + prefix_filter_out = ["10.0.1.0/24"] +} +``` + +### Multiple Prefixes + +```terraform +resource "scaleway_s2s_vpn_routing_policy" "policy" { + name = "my-routing-policy" + prefix_filter_in = ["10.0.2.0/24", "10.0.3.0/24"] + prefix_filter_out = ["10.0.1.0/24", "172.16.0.0/16"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `prefix_filter_in` - (Optional) List of IP prefixes (in CIDR notation) to accept from the peer gateway. These are the routes that the customer gateway can announce to Scaleway. +- `prefix_filter_out` - (Optional) List of IP prefixes (in CIDR notation) to advertise to the peer gateway. These are the routes that Scaleway will announce to the customer gateway. +- `name` - (Optional) The name of the routing policy. If not provided, it will be randomly generated. +- `tags` - (Optional) The list of tags to apply to the routing policy. +- `is_ipv6` - (Optional) Defines whether the routing policy is for IPv6 prefixes. Defaults to `false` (IPv4). +- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the routing policy should be created. +- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the routing policy is associated with. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The ID of the routing policy. +- `created_at` - The date and time of the creation of the routing policy (RFC 3339 format). +- `updated_at` - The date and time of the last update of the routing policy (RFC 3339 format). +- `organization_id` - The Organization ID the routing policy is associated with. + +~> **Important:** Routing Policies' 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` + +## Import + +Routing Policies can be imported using `{region}/{id}`, e.g. + +```bash +terraform import scaleway_s2s_vpn_routing_policy.main fr-par/11111111-1111-1111-1111-111111111111 +```