diff --git a/docs/resources/edge_services_backend_stage.md b/docs/resources/edge_services_backend_stage.md
new file mode 100644
index 000000000..190f43067
--- /dev/null
+++ b/docs/resources/edge_services_backend_stage.md
@@ -0,0 +1,58 @@
+---
+subcategory: "Edge Services"
+page_title: "Scaleway: scaleway_edge_services_backend_stage"
+---
+
+# Resource: scaleway_edge_services_backend_stage
+
+Creates and manages Scaleway Edge Services Backend Stages.
+
+## Example Usage
+
+### Basic
+
+```terraform
+resource "scaleway_object_bucket" "main" {
+ name = "my-bucket-name"
+ tags = {
+ foo = "bar"
+ }
+}
+
+resource "scaleway_edge_services_backend_stage" "main" {
+ s3_backend_config {
+ bucket_name = scaleway_object_bucket.main.name
+ bucket_region = "fr-par"
+ }
+}
+```
+
+### Custom Certificate
+
+```terraform
+```
+
+## Argument Reference
+
+- `s3_backend_config` - (Required) The Scaleway Object Storage origin bucket (S3) linked to the backend stage.
+ - `bucket_name` - The name of the Bucket.
+ - `bucket_region` - The region of the Bucket.
+ - `is_website` - Defines whether the bucket website feature is enabled.
+- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the backend stage is associated with.
+
+## Attributes Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+- `id` - The ID of the backend stage (UUID format).
+- `created_at` - The date and time of the creation of the backend stage.
+- `updated_at` - The date and time of the last update of the backend stage.
+- `pipeline_id` - The pipeline ID the backend stage belongs to.
+
+## Import
+
+Backend stages can be imported using the `{id}`, e.g.
+
+```bash
+$ terraform import scaleway_edge_services_backend_stage.basic 11111111-1111-1111-1111-111111111111
+```
diff --git a/docs/resources/edge_services_cache_stage.md b/docs/resources/edge_services_cache_stage.md
new file mode 100644
index 000000000..da9a4c011
--- /dev/null
+++ b/docs/resources/edge_services_cache_stage.md
@@ -0,0 +1,59 @@
+---
+subcategory: "Edge Services"
+page_title: "Scaleway: scaleway_edge_services_cache_stage"
+---
+
+# Resource: scaleway_edge_services_cache_stage
+
+Creates and manages Scaleway Edge Services Cache Stages.
+
+## Example Usage
+
+### Basic
+
+```terraform
+resource "scaleway_edge_services_cache_stage" "main" {
+ backend_stage_id = scaleway_edge_services_backend_stage.main.id
+}
+```
+
+### Purge request
+
+```terraform
+resource "scaleway_edge_services_cache_stage" "main" {
+ backend_stage_id = scaleway_edge_services_backend_stage.main.id
+
+ purge {
+ pipeline_id = scaleway_edge_services_pipeline.main.id
+ all = true
+ }
+}
+```
+
+## Argument Reference
+
+- `backend_stage_id` - (Optional) The backend stage ID the cache stage will be linked to.
+- `fallback_ttl` - (Optional) The Time To Live (TTL) in seconds. Defines how long content is cached.
+- `refresh_cache` - (Optional) Trigger a refresh of the cache by changing this field's value.
+- `purge_requests` - (Optional) The Scaleway Object Storage origin bucket (S3) linked to the backend stage.
+ - `pipeline_id` - The pipeline ID in which the purge request will be created.
+ - `assets` - The list of asserts to purge.
+ - `all` - Defines whether to purge all content.
+- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the cache stage is associated with.
+
+## Attributes Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+- `id` - The ID of the cache stage (UUID format).
+- `created_at` - The date and time of the creation of the cache stage.
+- `updated_at` - The date and time of the last update of the cache stage.
+- `pipeline_id` - The pipeline ID the cache stage belongs to.
+
+## Import
+
+Cache stages can be imported using the `{id}`, e.g.
+
+```bash
+$ terraform import scaleway_edge_services_cache_stage.basic 11111111-1111-1111-1111-111111111111
+```
diff --git a/docs/resources/edge_services_dns_stage.md b/docs/resources/edge_services_dns_stage.md
new file mode 100644
index 000000000..66cf3b2ee
--- /dev/null
+++ b/docs/resources/edge_services_dns_stage.md
@@ -0,0 +1,44 @@
+---
+subcategory: "Edge Services"
+page_title: "Scaleway: scaleway_edge_services_dns_stage"
+---
+
+# Resource: scaleway_edge_services_dns_stage
+
+Creates and manages Scaleway Edge Services DNS Stages.
+
+## Example Usage
+
+### Basic
+
+```terraform
+resource "scaleway_edge_services_dns_stage" "main" {
+ fqdns = ["subdomain.example.com"]
+}
+```
+
+## Argument Reference
+
+- `backend_stage_id` - (Optional) The backend stage ID the DNS stage will be linked to.
+- `tls_stage_id` - (Optional) The TLS stage ID the DNS stage will be linked to.
+- `cache_stage_id` - (Optional) The cache stage ID the DNS stage will be linked to.
+- `fqdns` - (Optional) Fully Qualified Domain Name (in the format subdomain.example.com) to attach to the stage.
+- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the DNS stage is associated with.
+
+## Attributes Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+- `id` - The ID of the DNS stage (UUID format).
+- `type` - The type of the stage.
+- `created_at` - The date and time of the creation of the DNS stage.
+- `updated_at` - The date and time of the last update of the DNS stage.
+- `pipeline_id` - The pipeline ID the DNS stage belongs to.
+
+## Import
+
+DNS stages can be imported using the `{id}`, e.g.
+
+```bash
+$ terraform import scaleway_edge_services_dns_stage.basic 11111111-1111-1111-1111-111111111111
+```
diff --git a/docs/resources/edge_services_pipeline.md b/docs/resources/edge_services_pipeline.md
new file mode 100644
index 000000000..722067d76
--- /dev/null
+++ b/docs/resources/edge_services_pipeline.md
@@ -0,0 +1,73 @@
+---
+subcategory: "Edge Services"
+page_title: "Scaleway: scaleway_edge_services_pipeline"
+---
+
+# Resource: scaleway_edge_services_pipeline
+
+Creates and manages Scaleway Edge Services Pipelines.
+
+## Example Usage
+
+### Basic
+
+```terraform
+resource "scaleway_edge_services_pipeline" "main" {
+ name = "pipeline-name"
+ description = "pipeline description"
+}
+```
+
+### Complete pipeline
+
+```terraform
+resource "scaleway_edge_services_backend_stage" "main" {
+ s3_backend_config {
+ bucket_name = "my-bucket-name"
+ bucket_region = "fr-par"
+ }
+}
+
+resource "scaleway_edge_services_tls_stage" "main" {
+ cache_stage_id = scaleway_edge_services_cache_stage.main.id
+ managed_certificate = true
+}
+
+resource "scaleway_edge_services_dns_stage" "main" {
+ tls_stage_id = scaleway_edge_services_tls_stage.main.id
+ fqdns = ["subdomain.example.com"]
+}
+
+resource "scaleway_edge_services_pipeline" "main" {
+ name = "my-edge_services-pipeline"
+ dns_stage_id = scaleway_edge_services_dns_stage.main.id
+}
+
+resource "scaleway_edge_services_cache_stage" "main" {
+ backend_stage_id = scaleway_edge_services_backend_stage.main.id
+}
+```
+
+## Argument Reference
+
+- `name` - (Optional) The name of the pipeline.
+- `description` - (Optional) The description of the pipeline.
+- `dns_stage_id` - (Optional) The DNS stage ID the pipeline will be attached to.
+- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the pipeline is associated with.
+
+## Attributes Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+- `id` - The ID of the pipeline (UUID format).
+- `created_at` - The date and time of the creation of the pipeline.
+- `updated_at` - The date and time of the last update of the pipeline.
+- `status` - The status of user pipeline.
+
+## Import
+
+Pipelines can be imported using the `{id}`, e.g.
+
+```bash
+$ terraform import scaleway_edge_services_pipeline.basic 11111111-1111-1111-1111-111111111111
+```
diff --git a/docs/resources/edge_services_tls_stage.md b/docs/resources/edge_services_tls_stage.md
new file mode 100644
index 000000000..f2dea11ab
--- /dev/null
+++ b/docs/resources/edge_services_tls_stage.md
@@ -0,0 +1,57 @@
+---
+subcategory: "Edge Services"
+page_title: "Scaleway: scaleway_edge_services_tls_stage"
+---
+
+# Resource: scaleway_edge_services_tls_stage
+
+Creates and manages Scaleway Edge Services TLS Stages.
+
+## Example Usage
+
+### Managed
+
+```terraform
+resource "scaleway_edge_services_tls_stage" "main" {
+ managed_certificate = true
+}
+```
+
+### With a certificate stored in Scaleway Secret Manager
+
+```terraform
+resource "scaleway_edge_services_tls_stage" "main" {
+ secrets {
+ secret_id = "11111111-1111-1111-1111-111111111111"
+ region = "fr-par"
+ }
+}
+```
+
+## Argument Reference
+
+- `backend_stage_id` - (Optional) The backend stage ID the TLS stage will be linked to.
+- `cache_stage_id` - (Optional) The cache stage ID the TLS stage will be linked to.
+- `managed_certificate` - (Optional) Set to true when Scaleway generates and manages a Let's Encrypt certificate for the TLS stage/custom endpoint.
+- `secrets` - (Optional) The TLS secrets.
+ - `bucket_name` - The ID of the secret.
+ - `region` - The region of the secret.
+- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the TLS stage is associated with.
+
+## Attributes Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+- `id` - The ID of the TLS stage (UUID format).
+- `certificate_expires_at` - The expiration date of the certificate.
+- `created_at` - The date and time of the creation of the TLS stage.
+- `updated_at` - The date and time of the last update of the TLS stage.
+- `pipeline_id` - The pipeline ID the TLS stage belongs to.
+
+## Import
+
+TLS stages can be imported using the `{id}`, e.g.
+
+```bash
+$ terraform import scaleway_edge_services_tls_stage.basic 11111111-1111-1111-1111-111111111111
+```
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 89239defe..0d81a9f1d 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -20,6 +20,7 @@ import (
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/cockpit"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/container"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/domain"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/flexibleip"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/function"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/iam"
@@ -135,6 +136,11 @@ func Provider(config *Config) plugin.ProviderFunc {
"scaleway_container_trigger": container.ResourceTrigger(),
"scaleway_domain_record": domain.ResourceRecord(),
"scaleway_domain_zone": domain.ResourceZone(),
+ "scaleway_edge_services_backend_stage": edgeservices.ResourceBackendStage(),
+ "scaleway_edge_services_cache_stage": edgeservices.ResourceCacheStage(),
+ "scaleway_edge_services_dns_stage": edgeservices.ResourceDNSStage(),
+ "scaleway_edge_services_pipeline": edgeservices.ResourcePipeline(),
+ "scaleway_edge_services_tls_stage": edgeservices.ResourceTLSStage(),
"scaleway_flexible_ip": flexibleip.ResourceIP(),
"scaleway_flexible_ip_mac_address": flexibleip.ResourceMACAddress(),
"scaleway_function": function.ResourceFunction(),
diff --git a/internal/services/edgeservices/backend_stage.go b/internal/services/edgeservices/backend_stage.go
new file mode 100644
index 000000000..57bd4fca7
--- /dev/null
+++ b/internal/services/edgeservices/backend_stage.go
@@ -0,0 +1,213 @@
+package edgeservices
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/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/zonal"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
+)
+
+func ResourceBackendStage() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: ResourceBackendStageCreate,
+ ReadContext: ResourceBackendStageRead,
+ UpdateContext: ResourceBackendStageUpdate,
+ DeleteContext: ResourceBackendStageDelete,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+ SchemaVersion: 0,
+ Schema: map[string]*schema.Schema{
+ "s3_backend_config": {
+ Type: schema.TypeList,
+ Optional: true,
+ ConflictsWith: []string{"lb_backend_config"},
+ MaxItems: 1,
+ Description: "The Scaleway Object Storage origin bucket (S3) linked to the backend stage",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "bucket_name": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The name of the Bucket",
+ },
+ "bucket_region": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The region of the Bucket",
+ },
+ "is_website": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Defines whether the bucket website feature is enabled.",
+ },
+ },
+ },
+ },
+ "lb_backend_config": {
+ Type: schema.TypeList,
+ Optional: true,
+ ConflictsWith: []string{"s3_backend_config"},
+ Description: "The Scaleway Load Balancer origin linked to the backend stage",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "lb_config": {
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: "The Load Balancer configuration",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "ID of the Load Balancer",
+ },
+ "frontend_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "ID of the frontend linked to the Load Balancer",
+ },
+ "is_ssl": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Defines whether the Load Balancer's frontend handles SSL connections",
+ },
+ "domain_name": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Fully Qualified Domain Name (in the format subdomain.example.com) to use in HTTP requests sent towards your Load Balancer",
+ },
+ "zone": zonal.Schema(),
+ },
+ },
+ },
+ },
+ },
+ },
+ "pipeline_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline ID the backend stage belongs to",
+ },
+ "created_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The date and time of the creation of the backend stage",
+ },
+ "updated_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The date and time of the last update of the backend stage",
+ },
+ "project_id": account.ProjectIDSchema(),
+ },
+ }
+}
+
+func ResourceBackendStageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ req := &edgeservices.CreateBackendStageRequest{
+ ProjectID: d.Get("project_id").(string),
+ }
+
+ if s3Config, ok := d.GetOk("s3_backend_config"); ok {
+ req.ScalewayS3 = expandS3BackendConfig(s3Config)
+ }
+
+ if lbConfig, ok := d.GetOk("lb_backend_config"); ok {
+ req.ScalewayLB = expandLBBackendConfig(lbConfig)
+ }
+
+ backendStage, err := api.CreateBackendStage(req, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(backendStage.ID)
+
+ return ResourceBackendStageRead(ctx, d, m)
+}
+
+func ResourceBackendStageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ backendStage, err := api.GetBackendStage(&edgeservices.GetBackendStageRequest{
+ BackendStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ if httperrors.Is404(err) {
+ d.SetId("")
+ return nil
+ }
+ return diag.FromErr(err)
+ }
+
+ _ = d.Set("pipeline_id", types.FlattenStringPtr(backendStage.PipelineID))
+ _ = d.Set("created_at", types.FlattenTime(backendStage.CreatedAt))
+ _ = d.Set("updated_at", types.FlattenTime(backendStage.UpdatedAt))
+ _ = d.Set("project_id", backendStage.ProjectID)
+ _ = d.Set("s3_backend_config", flattenS3BackendConfig(backendStage.ScalewayS3))
+ _ = d.Set("lb_backend_config", flattenLBBackendConfig(backendStage.ScalewayLB))
+
+ return nil
+}
+
+func ResourceBackendStageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ hasChanged := false
+
+ updateRequest := &edgeservices.UpdateBackendStageRequest{
+ BackendStageID: d.Id(),
+ }
+
+ if d.HasChange("s3_backend_config") {
+ updateRequest.ScalewayS3 = expandS3BackendConfig(d.Get("s3_backend_config"))
+ hasChanged = true
+ }
+
+ if d.HasChange("lb_backend_config") {
+ updateRequest.ScalewayLB = expandLBBackendConfig(d.Get("lb_backend_config"))
+ hasChanged = true
+ }
+
+ if hasChanged {
+ _, err := api.UpdateBackendStage(updateRequest, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ return ResourceBackendStageRead(ctx, d, m)
+}
+
+func ResourceBackendStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ err := retry.RetryContext(ctx, defaultEdgeServicesTimeout, func() *retry.RetryError {
+ err := api.DeleteBackendStage(&edgeservices.DeleteBackendStageRequest{
+ BackendStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil && !httperrors.Is403(err) {
+ if isStageUsedInPipelineError(err) {
+ return retry.RetryableError(err)
+ }
+ return retry.NonRetryableError(err)
+ }
+ return nil
+ })
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
diff --git a/internal/services/edgeservices/backend_stage_test.go b/internal/services/edgeservices/backend_stage_test.go
new file mode 100644
index 000000000..f27ae603d
--- /dev/null
+++ b/internal/services/edgeservices/backend_stage_test.go
@@ -0,0 +1,46 @@
+package edgeservices_test
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
+ edgeservicestestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices/testfuncs"
+)
+
+func TestAccEdgeServicesBackend_Basic(t *testing.T) {
+ tt := acctest.NewTestTools(t)
+ defer tt.Cleanup()
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { acctest.PreCheck(t) },
+ ProviderFactories: tt.ProviderFactories,
+ CheckDestroy: edgeservicestestfuncs.CheckEdgeServicesBackendDestroy(tt),
+ Steps: []resource.TestStep{
+ {
+ Config: `
+ resource "scaleway_object_bucket" "main" {
+ name = "test-acc-scaleway-object-bucket-basic-es"
+ tags = {
+ foo = "bar"
+ }
+ }
+
+ resource "scaleway_edge_services_backend_stage" "main" {
+ s3_backend_config {
+ bucket_name = scaleway_object_bucket.main.name
+ bucket_region = "fr-par"
+ }
+ }
+ `,
+ Check: resource.ComposeTestCheckFunc(
+ edgeservicestestfuncs.CheckEdgeServicesBackendExists(tt, "scaleway_edge_services_backend_stage.main"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_backend_stage.main", "s3_backend_config.0.is_website", "false"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_backend_stage.main", "s3_backend_config.0.bucket_region", "fr-par"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_backend_stage.main", "s3_backend_config.0.bucket_name"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_backend_stage.main", "created_at"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_backend_stage.main", "updated_at"),
+ ),
+ },
+ },
+ })
+}
diff --git a/internal/services/edgeservices/cache_stage.go b/internal/services/edgeservices/cache_stage.go
new file mode 100644
index 000000000..854234804
--- /dev/null
+++ b/internal/services/edgeservices/cache_stage.go
@@ -0,0 +1,198 @@
+package edgeservices
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edge_services "github.com/scaleway/scaleway-sdk-go/api/edge_services/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/services/account"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
+)
+
+func ResourceCacheStage() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: ResourceCacheStageCreate,
+ ReadContext: ResourceCacheStageRead,
+ UpdateContext: ResourceCacheStageUpdate,
+ DeleteContext: ResourceCacheStageDelete,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+ SchemaVersion: 0,
+ Schema: map[string]*schema.Schema{
+ "backend_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The backend stage ID the cache stage will be linked to",
+ },
+ "fallback_ttl": {
+ Type: schema.TypeInt,
+ Optional: true,
+ Default: 3600,
+ Description: "The Time To Live (TTL) in seconds. Defines how long content is cached",
+ },
+ "purge_requests": {
+ Type: schema.TypeSet,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "pipeline_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The pipeline ID in which the purge request will be created",
+ },
+ "assets": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "The list of asserts to purge",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "all": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Defines whether to purge all content",
+ },
+ },
+ },
+ },
+ "refresh_cache": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Trigger a refresh of the cache by changing this field's value",
+ },
+ "pipeline_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "created_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "updated_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "project_id": account.ProjectIDSchema(),
+ },
+ }
+}
+
+func ResourceCacheStageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ cacheStage, err := api.CreateCacheStage(&edge_services.CreateCacheStageRequest{
+ ProjectID: d.Get("project_id").(string),
+ BackendStageID: types.ExpandStringPtr(d.Get("backend_stage_id").(string)),
+ FallbackTTL: &scw.Duration{Seconds: int64(d.Get("fallback_ttl").(int))},
+ }, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(cacheStage.ID)
+
+ return ResourceCacheStageRead(ctx, d, m)
+}
+
+func ResourceCacheStageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ cacheStage, err := api.GetCacheStage(&edge_services.GetCacheStageRequest{
+ CacheStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ if httperrors.Is404(err) {
+ d.SetId("")
+ return nil
+ }
+ return diag.FromErr(err)
+ }
+
+ _ = d.Set("pipeline_id", types.FlattenStringPtr(cacheStage.PipelineID))
+ _ = d.Set("project_id", cacheStage.ProjectID)
+ _ = d.Set("created_at", types.FlattenTime(cacheStage.CreatedAt))
+ _ = d.Set("updated_at", types.FlattenTime(cacheStage.UpdatedAt))
+ _ = d.Set("backend_stage_id", types.FlattenStringPtr(cacheStage.BackendStageID))
+ _ = d.Set("fallback_ttl", cacheStage.FallbackTTL.Seconds)
+
+ return nil
+}
+
+func ResourceCacheStageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ hasChanged := false
+
+ updateRequest := &edge_services.UpdateCacheStageRequest{
+ CacheStageID: d.Id(),
+ }
+
+ if d.HasChange("backend_stage_id") {
+ updateRequest.BackendStageID = types.ExpandUpdatedStringPtr(d.Get("backend_stage_id"))
+ hasChanged = true
+ }
+
+ if d.HasChange("fallback_ttl") {
+ updateRequest.FallbackTTL = &scw.Duration{Seconds: int64(d.Get("fallback_ttl").(int))}
+ hasChanged = true
+ }
+
+ if hasChanged {
+ _, err := api.UpdateCacheStage(updateRequest, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ if d.HasChanges("purge_requests", "refresh_cache") {
+ for _, pr := range expandPurge(d.Get("purge_requests")) {
+ res, err := api.CreatePurgeRequest(&edge_services.CreatePurgeRequestRequest{
+ PipelineID: pr.PipelineID,
+ Assets: pr.Assets,
+ All: pr.All,
+ }, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ _, err = waitForPurge(ctx, api, res.ID, d.Timeout(schema.TimeoutUpdate))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+ }
+
+ return ResourceCacheStageRead(ctx, d, m)
+}
+
+func ResourceCacheStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ err := retry.RetryContext(ctx, defaultEdgeServicesTimeout, func() *retry.RetryError {
+ err := api.DeleteCacheStage(&edge_services.DeleteCacheStageRequest{
+ CacheStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil && !httperrors.Is403(err) {
+ if isStageUsedInPipelineError(err) {
+ return retry.RetryableError(err)
+ }
+ return retry.NonRetryableError(err)
+ }
+ return nil
+ })
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
diff --git a/internal/services/edgeservices/cache_stage_test.go b/internal/services/edgeservices/cache_stage_test.go
new file mode 100644
index 000000000..addfc692c
--- /dev/null
+++ b/internal/services/edgeservices/cache_stage_test.go
@@ -0,0 +1,32 @@
+package edgeservices_test
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
+ edgeservicestestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices/testfuncs"
+)
+
+func TestAccEdgeServicesCache_Basic(t *testing.T) {
+ tt := acctest.NewTestTools(t)
+ defer tt.Cleanup()
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { acctest.PreCheck(t) },
+ ProviderFactories: tt.ProviderFactories,
+ CheckDestroy: edgeservicestestfuncs.CheckEdgeServicesCacheDestroy(tt),
+ Steps: []resource.TestStep{
+ {
+ Config: `
+ resource "scaleway_edge_services_cache_stage" "main" {}
+ `,
+ Check: resource.ComposeTestCheckFunc(
+ edgeservicestestfuncs.CheckEdgeServicesCacheExists(tt, "scaleway_edge_services_cache_stage.main"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_cache_stage.main", "fallback_ttl", "3600"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_cache_stage.main", "created_at"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_cache_stage.main", "updated_at"),
+ ),
+ },
+ },
+ })
+}
diff --git a/internal/services/edgeservices/dns_stage.go b/internal/services/edgeservices/dns_stage.go
new file mode 100644
index 000000000..572b64717
--- /dev/null
+++ b/internal/services/edgeservices/dns_stage.go
@@ -0,0 +1,214 @@
+package edgeservices
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/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/services/account"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
+)
+
+func ResourceDNSStage() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: ResourceDNSStageCreate,
+ ReadContext: ResourceDNSStageRead,
+ UpdateContext: ResourceDNSStageUpdate,
+ DeleteContext: ResourceDNSStageDelete,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+ SchemaVersion: 0,
+ Schema: map[string]*schema.Schema{
+ "backend_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The backend stage ID the DNS stage will be linked to",
+ },
+ "tls_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The TLS stage ID the DNS stage will be linked to",
+ },
+ "cache_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The cache stage ID the DNS stage will be linked to",
+ },
+ "fqdns": {
+ Type: schema.TypeList,
+ Optional: true,
+ Computed: true,
+ Description: "Fully Qualified Domain Name (in the format subdomain.example.com) to attach to the stage",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The type of the stage",
+ },
+ "pipeline_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "TThe pipeline ID the DNS stage belongs to",
+ },
+ "created_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The date and time of the creation of the DNS stage",
+ },
+ "updated_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The date and time of the last update of the DNS stage",
+ },
+ "project_id": account.ProjectIDSchema(),
+ },
+ }
+}
+
+func ResourceDNSStageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ dnsStage, err := api.CreateDNSStage(&edgeservices.CreateDNSStageRequest{
+ ProjectID: d.Get("project_id").(string),
+ BackendStageID: types.ExpandStringPtr(d.Get("backend_stage_id").(string)),
+ CacheStageID: types.ExpandStringPtr(d.Get("cache_stage_id").(string)),
+ TLSStageID: types.ExpandStringPtr(d.Get("tls_stage_id").(string)),
+ Fqdns: types.ExpandStringsPtr(d.Get("fqdns")),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(dnsStage.ID)
+
+ return ResourceDNSStageRead(ctx, d, m)
+}
+
+func ResourceDNSStageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ dnsStage, err := api.GetDNSStage(&edgeservices.GetDNSStageRequest{
+ DNSStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ if httperrors.Is404(err) {
+ d.SetId("")
+ return nil
+ }
+ return diag.FromErr(err)
+ }
+
+ _ = d.Set("backend_stage_id", types.FlattenStringPtr(dnsStage.BackendStageID))
+ _ = d.Set("cache_stage_id", types.FlattenStringPtr(dnsStage.CacheStageID))
+ _ = d.Set("pipeline_id", types.FlattenStringPtr(dnsStage.PipelineID))
+ _ = d.Set("tls_stage_id", types.FlattenStringPtr(dnsStage.TLSStageID))
+ _ = d.Set("created_at", types.FlattenTime(dnsStage.CreatedAt))
+ _ = d.Set("updated_at", types.FlattenTime(dnsStage.UpdatedAt))
+ _ = d.Set("type", dnsStage.Type.String())
+ _ = d.Set("project_id", dnsStage.ProjectID)
+
+ oldFQDNs := d.Get("fqdns").([]interface{})
+ oldFQDNsSet := make(map[string]bool)
+ for _, fqdn := range oldFQDNs {
+ oldFQDNsSet[fqdn.(string)] = true
+ }
+
+ newFQDNs := make([]string, 0)
+ // add all FQDNs from the API response
+ for _, fqdn := range dnsStage.Fqdns {
+ if oldFQDNsSet[fqdn] || len(oldFQDNs) == 0 {
+ // keep FQDNs that were in the old state or if there were no old FQDNs
+ newFQDNs = append(newFQDNs, fqdn)
+ }
+ }
+ // add any FQDNs from the old state that aren't in the API response
+ for _, oldFQDN := range oldFQDNs {
+ found := false
+ for _, newFQDN := range newFQDNs {
+ if oldFQDN.(string) == newFQDN {
+ found = true
+ break
+ }
+ }
+ if !found {
+ newFQDNs = append(newFQDNs, oldFQDN.(string))
+ }
+ }
+ if err = d.Set("fqdns", newFQDNs); err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
+
+func ResourceDNSStageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ hasChanged := false
+
+ updateRequest := &edgeservices.UpdateDNSStageRequest{
+ DNSStageID: d.Id(),
+ }
+
+ if d.HasChange("backend_stage_id") {
+ updateRequest.BackendStageID = types.ExpandUpdatedStringPtr(d.Get("backend_stage_id"))
+ hasChanged = true
+ }
+
+ if d.HasChange("cache_stage_id") {
+ updateRequest.CacheStageID = types.ExpandUpdatedStringPtr(d.Get("cache_stage_id"))
+ hasChanged = true
+ }
+
+ if d.HasChange("tls_stage_id") {
+ updateRequest.TLSStageID = types.ExpandUpdatedStringPtr(d.Get("tls_stage_id"))
+ hasChanged = true
+ }
+
+ if d.HasChange("fqdns") {
+ updateRequest.Fqdns = types.ExpandUpdatedStringsPtr(d.Get("fqdns"))
+ hasChanged = true
+ }
+
+ if hasChanged {
+ _, err := api.UpdateDNSStage(updateRequest, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ return ResourceDNSStageRead(ctx, d, m)
+}
+
+func ResourceDNSStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ err := retry.RetryContext(ctx, defaultEdgeServicesTimeout, func() *retry.RetryError {
+ err := api.DeleteDNSStage(&edgeservices.DeleteDNSStageRequest{
+ DNSStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil && !httperrors.Is403(err) {
+ if isStageUsedInPipelineError(err) {
+ return retry.RetryableError(err)
+ }
+ return retry.NonRetryableError(err)
+ }
+ return nil
+ })
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
diff --git a/internal/services/edgeservices/dns_stage_test.go b/internal/services/edgeservices/dns_stage_test.go
new file mode 100644
index 000000000..9eb82f91e
--- /dev/null
+++ b/internal/services/edgeservices/dns_stage_test.go
@@ -0,0 +1,35 @@
+package edgeservices_test
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
+ edgeservicestestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices/testfuncs"
+)
+
+func TestAccEdgeServicesDNS_Basic(t *testing.T) {
+ tt := acctest.NewTestTools(t)
+ defer tt.Cleanup()
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { acctest.PreCheck(t) },
+ ProviderFactories: tt.ProviderFactories,
+ CheckDestroy: edgeservicestestfuncs.CheckEdgeServicesDNSDestroy(tt),
+ Steps: []resource.TestStep{
+ {
+ Config: `
+ resource "scaleway_edge_services_dns_stage" "main" {
+ fqdns = ["subodomain.example.fr"]
+ }
+ `,
+ Check: resource.ComposeTestCheckFunc(
+ edgeservicestestfuncs.CheckEdgeServicesDNSExists(tt, "scaleway_edge_services_dns_stage.main"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_dns_stage.main", "fqdns.0", "subodomain.example.fr"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_dns_stage.main", "type"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_dns_stage.main", "created_at"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_dns_stage.main", "updated_at"),
+ ),
+ },
+ },
+ })
+}
diff --git a/internal/services/edgeservices/helpers.go b/internal/services/edgeservices/helpers.go
new file mode 100644
index 000000000..0e6f70a1b
--- /dev/null
+++ b/internal/services/edgeservices/helpers.go
@@ -0,0 +1,42 @@
+package edgeservices
+
+import (
+ "errors"
+ "net/http"
+ "strings"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/v1alpha1"
+ "github.com/scaleway/scaleway-sdk-go/scw"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
+)
+
+// NewEdgeServicesAPI returns a new edge_services API
+func NewEdgeServicesAPI(m interface{}) *edgeservices.API {
+ return edgeservices.NewAPI(meta.ExtractScwClient(m))
+}
+
+// NewEdgeServicesAPIWithRegion returns a new edge_services API and the region
+func NewEdgeServicesAPIWithRegion(d *schema.ResourceData, m interface{}) (*edgeservices.API, scw.Region, error) {
+ api := edgeservices.NewAPI(meta.ExtractScwClient(m))
+
+ region, err := meta.ExtractRegion(d, m)
+ if err != nil {
+ return nil, "", err
+ }
+ return api, region, err
+}
+
+func isStageUsedInPipelineError(err error) bool {
+ if err == nil {
+ return false
+ }
+
+ responseError := &scw.ResponseError{}
+ if errors.As(err, &responseError) && responseError.StatusCode == http.StatusBadRequest {
+ if strings.Contains(responseError.Message, "operation was rejected because the stage stage is used in a pipeline") {
+ return true
+ }
+ }
+ return false
+}
diff --git a/internal/services/edgeservices/pipeline.go b/internal/services/edgeservices/pipeline.go
new file mode 100644
index 000000000..09a940132
--- /dev/null
+++ b/internal/services/edgeservices/pipeline.go
@@ -0,0 +1,158 @@
+package edgeservices
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/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"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
+)
+
+func ResourcePipeline() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: ResourcePipelineCreate,
+ ReadContext: ResourcePipelineRead,
+ UpdateContext: ResourcePipelineUpdate,
+ DeleteContext: ResourcePipelineDelete,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+ Timeouts: &schema.ResourceTimeout{
+ Create: schema.DefaultTimeout(defaultEdgeServicesTimeout),
+ Read: schema.DefaultTimeout(defaultEdgeServicesTimeout),
+ Update: schema.DefaultTimeout(defaultEdgeServicesTimeout),
+ Delete: schema.DefaultTimeout(defaultEdgeServicesTimeout),
+ Default: schema.DefaultTimeout(defaultEdgeServicesTimeout),
+ },
+ SchemaVersion: 0,
+ Schema: map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The pipeline name",
+ },
+ "description": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The pipeline description",
+ },
+ "status": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "dns_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "created_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "updated_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline description",
+ },
+ "project_id": account.ProjectIDSchema(),
+ },
+ }
+}
+
+func ResourcePipelineCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ pipeline, err := api.CreatePipeline(&edgeservices.CreatePipelineRequest{
+ Description: d.Get("description").(string),
+ ProjectID: d.Get("project_id").(string),
+ Name: d.Get("name").(string),
+ DNSStageID: types.ExpandStringPtr(locality.ExpandID(d.Get("dns_stage_id").(string))),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(pipeline.ID)
+
+ return ResourcePipelineRead(ctx, d, m)
+}
+
+func ResourcePipelineRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ pipeline, err := api.GetPipeline(&edgeservices.GetPipelineRequest{
+ PipelineID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ if httperrors.Is404(err) {
+ d.SetId("")
+ return nil
+ }
+ return diag.FromErr(err)
+ }
+
+ _ = d.Set("name", pipeline.Name)
+ _ = d.Set("description", pipeline.Description)
+ _ = d.Set("dns_stage_id", types.FlattenStringPtr(pipeline.DNSStageID))
+ _ = d.Set("created_at", types.FlattenTime(pipeline.CreatedAt))
+ _ = d.Set("updated_at", types.FlattenTime(pipeline.UpdatedAt))
+ _ = d.Set("status", pipeline.Status.String())
+ _ = d.Set("project_id", pipeline.ProjectID)
+
+ return nil
+}
+
+func ResourcePipelineUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ hasChanged := false
+
+ updateRequest := &edgeservices.UpdatePipelineRequest{
+ PipelineID: d.Id(),
+ }
+
+ if d.HasChange("name") {
+ updateRequest.Name = types.ExpandUpdatedStringPtr(d.Get("name"))
+ hasChanged = true
+ }
+
+ if d.HasChange("description") {
+ updateRequest.Description = types.ExpandUpdatedStringPtr(d.Get("description"))
+ hasChanged = true
+ }
+
+ if d.HasChange("dns_stage_id") {
+ updateRequest.DNSStageID = types.ExpandUpdatedStringPtr(d.Get("dns_stage_id"))
+ hasChanged = true
+ }
+
+ if hasChanged {
+ _, err := api.UpdatePipeline(updateRequest, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ return ResourcePipelineRead(ctx, d, m)
+}
+
+func ResourcePipelineDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ err := api.DeletePipeline(&edgeservices.DeletePipelineRequest{
+ PipelineID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil && !httperrors.Is404(err) {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
diff --git a/internal/services/edgeservices/pipeline_test.go b/internal/services/edgeservices/pipeline_test.go
new file mode 100644
index 000000000..8e1398511
--- /dev/null
+++ b/internal/services/edgeservices/pipeline_test.go
@@ -0,0 +1,36 @@
+package edgeservices_test
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
+ edgeservicestestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices/testfuncs"
+)
+
+func TestAccEdgeServicesPipeline_Basic(t *testing.T) {
+ tt := acctest.NewTestTools(t)
+ defer tt.Cleanup()
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { acctest.PreCheck(t) },
+ ProviderFactories: tt.ProviderFactories,
+ CheckDestroy: edgeservicestestfuncs.CheckEdgeServicesCacheDestroy(tt),
+ Steps: []resource.TestStep{
+ {
+ Config: `
+ resource "scaleway_edge_services_pipeline" "main" {
+ name = "tf-tests-pipeline-name"
+ description = "a description"
+ }
+ `,
+ Check: resource.ComposeTestCheckFunc(
+ edgeservicestestfuncs.CheckEdgeServicesPipelineExists(tt, "scaleway_edge_services_pipeline.main"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_pipeline.main", "name", "tf-tests-pipeline-name"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_pipeline.main", "description", "a description"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_pipeline.main", "created_at"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_pipeline.main", "updated_at"),
+ ),
+ },
+ },
+ })
+}
diff --git a/internal/services/edgeservices/sweep_test.go b/internal/services/edgeservices/sweep_test.go
new file mode 100644
index 000000000..ceaa69760
--- /dev/null
+++ b/internal/services/edgeservices/sweep_test.go
@@ -0,0 +1,16 @@
+package edgeservices_test
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ edgeservicestestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices/testfuncs"
+)
+
+func init() {
+ edgeservicestestfuncs.AddTestSweepers()
+}
+
+func TestMain(m *testing.M) {
+ resource.TestMain(m)
+}
diff --git a/internal/services/edgeservices/testdata/edge-services-backend-basic.cassette.yaml b/internal/services/edgeservices/testdata/edge-services-backend-basic.cassette.yaml
new file mode 100644
index 000000000..0f2489b7c
--- /dev/null
+++ b/internal/services/edgeservices/testdata/edge-services-backend-basic.cassette.yaml
@@ -0,0 +1,1176 @@
+---
+version: 2
+interactions:
+ - id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 150
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: fr-par
+ form: {}
+ headers:
+ Content-Length:
+ - "150"
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Acl:
+ - private
+ X-Amz-Bucket-Object-Lock-Enabled:
+ - "false"
+ X-Amz-Content-Sha256:
+ - 2cb57fad7b7168921a4c94426cfcb9ee2953f126430595df844e22d50f029060
+ X-Amz-Date:
+ - 20240627T152503Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/
+ method: PUT
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 0
+ uncompressed: false
+ body: ""
+ headers:
+ Content-Length:
+ - "0"
+ Date:
+ - Thu, 27 Jun 2024 15:25:03 GMT
+ Location:
+ - /test-acc-scaleway-object-bucket-basic-es
+ X-Amz-Id-2:
+ - txgf5f0c189a1ae4838b387-00667d844f
+ X-Amz-Request-Id:
+ - txgf5f0c189a1ae4838b387-00667d844f
+ status: 200 OK
+ code: 200
+ duration: 476.643157ms
+ - id: 1
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 127
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: foobar
+ form: {}
+ headers:
+ Content-Length:
+ - "127"
+ Content-Md5:
+ - GLaI7og/rAKomUfPePCCFQ==
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - d68cba1a39d89eb72e49b2e5b04058846b60e88e6e32eae42901c4f57a4727a8
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?tagging=
+ method: PUT
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 0
+ uncompressed: false
+ body: ""
+ headers:
+ Content-Length:
+ - "0"
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txgcf3efa24fc4247ed8cb0-00667d8450
+ X-Amz-Request-Id:
+ - txgcf3efa24fc4247ed8cb0-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 141.336796ms
+ - id: 2
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ Content-Md5:
+ - 1B2M2Y8AsgTpgAmY7PhCfg==
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Acl:
+ - private
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?acl=
+ method: PUT
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 0
+ uncompressed: false
+ body: ""
+ headers:
+ Content-Length:
+ - "0"
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txg01fac485da8e4718b040-00667d8450
+ X-Amz-Request-Id:
+ - txg01fac485da8e4718b040-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 78.257158ms
+ - id: 3
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 127
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: foobar
+ form: {}
+ headers:
+ Content-Length:
+ - "127"
+ Content-Md5:
+ - GLaI7og/rAKomUfPePCCFQ==
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - d68cba1a39d89eb72e49b2e5b04058846b60e88e6e32eae42901c4f57a4727a8
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?tagging=
+ method: PUT
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 0
+ uncompressed: false
+ body: ""
+ headers:
+ Content-Length:
+ - "0"
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txgae670688b42a474fa18e-00667d8450
+ X-Amz-Request-Id:
+ - txgae670688b42a474fa18e-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 92.135192ms
+ - id: 4
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?acl=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 698
+ uncompressed: false
+ body: |-
+
+ 105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecf105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecf105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecf105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecfFULL_CONTROL
+ headers:
+ Content-Length:
+ - "698"
+ Content-Type:
+ - text/xml; charset=utf-8
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txg6a40d85c7e8642ffbed8-00667d8450
+ X-Amz-Request-Id:
+ - txg6a40d85c7e8642ffbed8-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 133.819223ms
+ - id: 5
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?object-lock=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 309
+ uncompressed: false
+ body: ObjectLockConfigurationNotFoundError
Object Lock configuration does not exist for this buckettxgc36bd3a74bb84ba396f2-00667d8450txgc36bd3a74bb84ba396f2-00667d8450/test-acc-scaleway-object-bucket-basic-es
+ headers:
+ Content-Length:
+ - "309"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txgc36bd3a74bb84ba396f2-00667d8450
+ X-Amz-Request-Id:
+ - txgc36bd3a74bb84ba396f2-00667d8450
+ status: 404 Not Found
+ code: 404
+ duration: 62.551073ms
+ - id: 6
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 266
+ uncompressed: false
+ body: |-
+
+ test-acc-scaleway-object-bucket-basic-es1000false
+ headers:
+ Content-Length:
+ - "266"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txgee25f5d5fb7a4b8ab68d-00667d8450
+ X-Amz-Request-Id:
+ - txgee25f5d5fb7a4b8ab68d-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 87.353226ms
+ - id: 7
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?tagging=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 118
+ uncompressed: false
+ body: |-
+
+ foobar
+ headers:
+ Content-Length:
+ - "118"
+ Content-Type:
+ - text/xml; charset=utf-8
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txg8dfc27357dbf4eb2b5f6-00667d8450
+ X-Amz-Request-Id:
+ - txg8dfc27357dbf4eb2b5f6-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 61.689223ms
+ - id: 8
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?cors=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 277
+ uncompressed: false
+ body: NoSuchCORSConfiguration
The CORS configuration does not existtxg06f3bac3029347739068-00667d8450txg06f3bac3029347739068-00667d8450/test-acc-scaleway-object-bucket-basic-es
+ headers:
+ Content-Length:
+ - "277"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txg06f3bac3029347739068-00667d8450
+ X-Amz-Request-Id:
+ - txg06f3bac3029347739068-00667d8450
+ status: 404 Not Found
+ code: 404
+ duration: 46.307588ms
+ - id: 9
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?versioning=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 138
+ uncompressed: false
+ body: |-
+
+
+ headers:
+ Content-Length:
+ - "138"
+ Content-Type:
+ - text/xml; charset=utf-8
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txg852f27b52413476984d6-00667d8450
+ X-Amz-Request-Id:
+ - txg852f27b52413476984d6-00667d8450
+ status: 200 OK
+ code: 200
+ duration: 45.279489ms
+ - id: 10
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152504Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?lifecycle=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 287
+ uncompressed: false
+ body: NoSuchLifecycleConfiguration
The lifecycle configuration does not existtxgfb9546e2a05640a39231-00667d8450txgfb9546e2a05640a39231-00667d8450/test-acc-scaleway-object-bucket-basic-es
+ headers:
+ Content-Length:
+ - "287"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:04 GMT
+ X-Amz-Id-2:
+ - txgfb9546e2a05640a39231-00667d8450
+ X-Amz-Request-Id:
+ - txgfb9546e2a05640a39231-00667d8450
+ status: 404 Not Found
+ code: 404
+ duration: 24.849527ms
+ - id: 11
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 170
+ transfer_encoding: []
+ trailer: {}
+ host: api.scaleway.com
+ remote_addr: ""
+ request_uri: ""
+ body: '{"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","scaleway_s3":{"bucket_name":"test-acc-scaleway-object-bucket-basic-es","bucket_region":"fr-par","is_website":false}}'
+ form: {}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/backend-stages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 325
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T15:25:05.313045047Z","id":"f8311f16-fb7a-4b1b-b4e1-47883cbbd53c","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","scaleway_s3":{"bucket_name":"test-acc-scaleway-object-bucket-basic-es","bucket_region":"fr-par","is_website":false},"updated_at":"2024-06-27T15:25:05.313045047Z"}'
+ headers:
+ Content-Length:
+ - "325"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 15:25:05 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-3;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - e54abac6-ac59-4784-98b2-096ce5996ba5
+ status: 200 OK
+ code: 200
+ duration: 343.72632ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/backend-stages/f8311f16-fb7a-4b1b-b4e1-47883cbbd53c
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 319
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T15:25:05.313045Z","id":"f8311f16-fb7a-4b1b-b4e1-47883cbbd53c","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","scaleway_s3":{"bucket_name":"test-acc-scaleway-object-bucket-basic-es","bucket_region":"fr-par","is_website":false},"updated_at":"2024-06-27T15:25:05.313045Z"}'
+ headers:
+ Content-Length:
+ - "319"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 15:25:05 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-3;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 61665476-f116-4d5b-8e17-d4768e55936d
+ status: 200 OK
+ code: 200
+ duration: 117.471296ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/backend-stages/f8311f16-fb7a-4b1b-b4e1-47883cbbd53c
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 319
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T15:25:05.313045Z","id":"f8311f16-fb7a-4b1b-b4e1-47883cbbd53c","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","scaleway_s3":{"bucket_name":"test-acc-scaleway-object-bucket-basic-es","bucket_region":"fr-par","is_website":false},"updated_at":"2024-06-27T15:25:05.313045Z"}'
+ headers:
+ Content-Length:
+ - "319"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 15:25:05 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-3;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - f94cec47-4e38-44c1-86a9-3e1ee8282b33
+ status: 200 OK
+ code: 200
+ duration: 114.732577ms
+ - id: 14
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?acl=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 698
+ uncompressed: false
+ body: |-
+
+ 105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecf105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecf105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecf105bdce1-64c0-48ab-899d-868455867ecf:105bdce1-64c0-48ab-899d-868455867ecfFULL_CONTROL
+ headers:
+ Content-Length:
+ - "698"
+ Content-Type:
+ - text/xml; charset=utf-8
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txg366e6910183b4b0a8a8d-00667d8452
+ X-Amz-Request-Id:
+ - txg366e6910183b4b0a8a8d-00667d8452
+ status: 200 OK
+ code: 200
+ duration: 37.410316ms
+ - id: 15
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?object-lock=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 309
+ uncompressed: false
+ body: ObjectLockConfigurationNotFoundError
Object Lock configuration does not exist for this buckettxg0303add91c0a4f6f94ae-00667d8452txg0303add91c0a4f6f94ae-00667d8452/test-acc-scaleway-object-bucket-basic-es
+ headers:
+ Content-Length:
+ - "309"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txg0303add91c0a4f6f94ae-00667d8452
+ X-Amz-Request-Id:
+ - txg0303add91c0a4f6f94ae-00667d8452
+ status: 404 Not Found
+ code: 404
+ duration: 54.086864ms
+ - id: 16
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 266
+ uncompressed: false
+ body: |-
+
+ test-acc-scaleway-object-bucket-basic-es1000false
+ headers:
+ Content-Length:
+ - "266"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txg73af05dcbe1e488c850f-00667d8452
+ X-Amz-Request-Id:
+ - txg73af05dcbe1e488c850f-00667d8452
+ status: 200 OK
+ code: 200
+ duration: 114.595504ms
+ - id: 17
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?tagging=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 118
+ uncompressed: false
+ body: |-
+
+ foobar
+ headers:
+ Content-Length:
+ - "118"
+ Content-Type:
+ - text/xml; charset=utf-8
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txg1d55ad53c51947019f97-00667d8452
+ X-Amz-Request-Id:
+ - txg1d55ad53c51947019f97-00667d8452
+ status: 200 OK
+ code: 200
+ duration: 38.887944ms
+ - id: 18
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?cors=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 277
+ uncompressed: false
+ body: NoSuchCORSConfiguration
The CORS configuration does not existtxg79625b11bd5c4ec4b7e5-00667d8452txg79625b11bd5c4ec4b7e5-00667d8452/test-acc-scaleway-object-bucket-basic-es
+ headers:
+ Content-Length:
+ - "277"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txg79625b11bd5c4ec4b7e5-00667d8452
+ X-Amz-Request-Id:
+ - txg79625b11bd5c4ec4b7e5-00667d8452
+ status: 404 Not Found
+ code: 404
+ duration: 36.923543ms
+ - id: 19
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?versioning=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 138
+ uncompressed: false
+ body: |-
+
+
+ headers:
+ Content-Length:
+ - "138"
+ Content-Type:
+ - text/xml; charset=utf-8
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txg654c413508234754a5a8-00667d8452
+ X-Amz-Request-Id:
+ - txg654c413508234754a5a8-00667d8452
+ status: 200 OK
+ code: 200
+ duration: 69.143217ms
+ - id: 20
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152506Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/?lifecycle=
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 287
+ uncompressed: false
+ body: NoSuchLifecycleConfiguration
The lifecycle configuration does not existtxgb22b968002a04d90ba7d-00667d8452txgb22b968002a04d90ba7d-00667d8452/test-acc-scaleway-object-bucket-basic-es
+ headers:
+ Content-Length:
+ - "287"
+ Content-Type:
+ - application/xml
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ X-Amz-Id-2:
+ - txgb22b968002a04d90ba7d-00667d8452
+ X-Amz-Request-Id:
+ - txgb22b968002a04d90ba7d-00667d8452
+ status: 404 Not Found
+ code: 404
+ duration: 45.453296ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/backend-stages/f8311f16-fb7a-4b1b-b4e1-47883cbbd53c
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 319
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T15:25:05.313045Z","id":"f8311f16-fb7a-4b1b-b4e1-47883cbbd53c","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","scaleway_s3":{"bucket_name":"test-acc-scaleway-object-bucket-basic-es","bucket_region":"fr-par","is_website":false},"updated_at":"2024-06-27T15:25:05.313045Z"}'
+ headers:
+ Content-Length:
+ - "319"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 15:25:06 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-3;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 44173ee1-7f40-4bec-a755-1dd7f79d3491
+ status: 200 OK
+ code: 200
+ duration: 88.214264ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/backend-stages/f8311f16-fb7a-4b1b-b4e1-47883cbbd53c
+ 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:
+ - Thu, 27 Jun 2024 15:25:07 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-3;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 9878a632-e0e9-4f02-8651-7962692404c2
+ status: 204 No Content
+ code: 204
+ duration: 112.987009ms
+ - id: 23
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 0
+ transfer_encoding: []
+ trailer: {}
+ host: test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud
+ remote_addr: ""
+ request_uri: ""
+ body: ""
+ form: {}
+ headers:
+ User-Agent:
+ - aws-sdk-go/1.54.6 (go1.22.2; darwin; amd64)
+ X-Amz-Content-Sha256:
+ - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ X-Amz-Date:
+ - 20240627T152507Z
+ url: https://test-acc-scaleway-object-bucket-basic-es.s3.fr-par.scw.cloud/
+ method: DELETE
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 0
+ uncompressed: false
+ body: ""
+ headers:
+ Date:
+ - Thu, 27 Jun 2024 15:25:07 GMT
+ X-Amz-Id-2:
+ - txg0258e6ca4f9942d48c6b-00667d8453
+ X-Amz-Request-Id:
+ - txg0258e6ca4f9942d48c6b-00667d8453
+ status: 204 No Content
+ code: 204
+ duration: 145.68776ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/backend-stages/f8311f16-fb7a-4b1b-b4e1-47883cbbd53c
+ method: DELETE
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 31
+ uncompressed: false
+ body: '{"message":"Permission denied"}'
+ headers:
+ Content-Length:
+ - "31"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 15:25:07 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-3;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - a0469290-9760-4ba7-bfd9-1a8b30a7b3c4
+ status: 403 Forbidden
+ code: 403
+ duration: 149.289297ms
diff --git a/internal/services/edgeservices/testdata/edge-services-cache-basic.cassette.yaml b/internal/services/edgeservices/testdata/edge-services-cache-basic.cassette.yaml
new file mode 100644
index 000000000..d9856a8e9
--- /dev/null
+++ b/internal/services/edgeservices/testdata/edge-services-cache-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: 86
+ transfer_encoding: []
+ trailer: {}
+ host: api.scaleway.com
+ remote_addr: ""
+ request_uri: ""
+ body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","fallback_ttl":"3600.000000000s"}'
+ form: {}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/cache-stages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 236
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T13:58:37.708453781Z","fallback_ttl":"3600s","id":"c4d7351d-4a70-46db-bf45-5c14be056703","pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","updated_at":"2024-06-27T13:58:37.708453781Z"}'
+ headers:
+ Content-Length:
+ - "236"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 13:58:37 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-1;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 25aaad51-58a3-45a3-b300-09e4ad32ca98
+ status: 200 OK
+ code: 200
+ duration: 112.406301ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/cache-stages/c4d7351d-4a70-46db-bf45-5c14be056703
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 230
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T13:58:37.708453Z","fallback_ttl":"3600s","id":"c4d7351d-4a70-46db-bf45-5c14be056703","pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","updated_at":"2024-06-27T13:58:37.708453Z"}'
+ headers:
+ Content-Length:
+ - "230"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 13:58:37 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-1;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - a220e432-f86c-4493-978b-11d9c8dce34b
+ status: 200 OK
+ code: 200
+ duration: 52.318292ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/cache-stages/c4d7351d-4a70-46db-bf45-5c14be056703
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 230
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T13:58:37.708453Z","fallback_ttl":"3600s","id":"c4d7351d-4a70-46db-bf45-5c14be056703","pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","updated_at":"2024-06-27T13:58:37.708453Z"}'
+ headers:
+ Content-Length:
+ - "230"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 13:58:37 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-1;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 3903f7ff-7269-432a-8de0-b4a9099c67d7
+ status: 200 OK
+ code: 200
+ duration: 39.696786ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/cache-stages/c4d7351d-4a70-46db-bf45-5c14be056703
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 230
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T13:58:37.708453Z","fallback_ttl":"3600s","id":"c4d7351d-4a70-46db-bf45-5c14be056703","pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","updated_at":"2024-06-27T13:58:37.708453Z"}'
+ headers:
+ Content-Length:
+ - "230"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 13:58:38 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-1;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - fe8b91f9-1f63-46dc-a388-30e4eee6ed75
+ status: 200 OK
+ code: 200
+ duration: 59.333501ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/cache-stages/c4d7351d-4a70-46db-bf45-5c14be056703
+ 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:
+ - Thu, 27 Jun 2024 13:58:38 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-1;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 544b0216-e711-48ba-8f20-2dc3193bcf73
+ status: 204 No Content
+ code: 204
+ duration: 54.392247ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/cache-stages/c4d7351d-4a70-46db-bf45-5c14be056703
+ method: DELETE
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 31
+ uncompressed: false
+ body: '{"message":"Permission denied"}'
+ headers:
+ Content-Length:
+ - "31"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 13:58:38 GMT
+ Server:
+ - Scaleway API Gateway (fr-par-1;edge01)
+ Strict-Transport-Security:
+ - max-age=63072000
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - DENY
+ X-Request-Id:
+ - 13e22b91-e874-487c-9a8b-b608ec4aecd1
+ status: 403 Forbidden
+ code: 403
+ duration: 48.898655ms
diff --git a/internal/services/edgeservices/testdata/edge-services-dns-basic.cassette.yaml b/internal/services/edgeservices/testdata/edge-services-dns-basic.cassette.yaml
new file mode 100644
index 000000000..7e7d76960
--- /dev/null
+++ b/internal/services/edgeservices/testdata/edge-services-dns-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: 87
+ transfer_encoding: []
+ trailer: {}
+ host: api.scaleway.com
+ remote_addr: ""
+ request_uri: ""
+ body: '{"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","fqdns":["subodomain.example.fr"]}'
+ form: {}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/dns-stages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 258
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:47:06.829896869Z","fqdns":["subodomain.example.fr"],"id":"f8e65c05-992b-4cd7-a2b1-ac3c0456063e","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","type":"custom","updated_at":"2024-06-27T14:47:06.829896869Z"}'
+ headers:
+ Content-Length:
+ - "258"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:47:06 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:
+ - 96c741ff-c2cd-42a1-80f7-d3aead3f5ddd
+ status: 200 OK
+ code: 200
+ duration: 440.302352ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/dns-stages/f8e65c05-992b-4cd7-a2b1-ac3c0456063e
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 252
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:47:06.829896Z","fqdns":["subodomain.example.fr"],"id":"f8e65c05-992b-4cd7-a2b1-ac3c0456063e","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","type":"custom","updated_at":"2024-06-27T14:47:06.829896Z"}'
+ headers:
+ Content-Length:
+ - "252"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:47:07 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:
+ - 05721dcf-d569-4d01-be10-4f4cd12543b2
+ status: 200 OK
+ code: 200
+ duration: 73.590582ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/dns-stages/f8e65c05-992b-4cd7-a2b1-ac3c0456063e
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 252
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:47:06.829896Z","fqdns":["subodomain.example.fr"],"id":"f8e65c05-992b-4cd7-a2b1-ac3c0456063e","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","type":"custom","updated_at":"2024-06-27T14:47:06.829896Z"}'
+ headers:
+ Content-Length:
+ - "252"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:47:07 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:
+ - b31e6224-d08b-4adf-96bb-cc79fe37fb75
+ status: 200 OK
+ code: 200
+ duration: 81.442921ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/dns-stages/f8e65c05-992b-4cd7-a2b1-ac3c0456063e
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 252
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:47:06.829896Z","fqdns":["subodomain.example.fr"],"id":"f8e65c05-992b-4cd7-a2b1-ac3c0456063e","pipeline_id":null,"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","type":"custom","updated_at":"2024-06-27T14:47:06.829896Z"}'
+ headers:
+ Content-Length:
+ - "252"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:47:07 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:
+ - 4ff86b8f-59e3-4a31-96fc-3189f48c3273
+ status: 200 OK
+ code: 200
+ duration: 78.502848ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/dns-stages/f8e65c05-992b-4cd7-a2b1-ac3c0456063e
+ 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:
+ - Thu, 27 Jun 2024 14:47:08 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:
+ - 72389695-1341-4cba-b369-39b3e7503590
+ status: 204 No Content
+ code: 204
+ duration: 96.488639ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/dns-stages/f8e65c05-992b-4cd7-a2b1-ac3c0456063e
+ method: DELETE
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 31
+ uncompressed: false
+ body: '{"message":"Permission denied"}'
+ headers:
+ Content-Length:
+ - "31"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:47:08 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:
+ - accb7afc-aa4b-4d6a-941f-bc242dfe056f
+ status: 403 Forbidden
+ code: 403
+ duration: 81.271014ms
diff --git a/internal/services/edgeservices/testdata/edge-services-pipeline-basic.cassette.yaml b/internal/services/edgeservices/testdata/edge-services-pipeline-basic.cassette.yaml
new file mode 100644
index 000000000..1916cb650
--- /dev/null
+++ b/internal/services/edgeservices/testdata/edge-services-pipeline-basic.cassette.yaml
@@ -0,0 +1,250 @@
+---
+version: 2
+interactions:
+ - id: 0
+ request:
+ proto: HTTP/1.1
+ proto_major: 1
+ proto_minor: 1
+ content_length: 115
+ transfer_encoding: []
+ trailer: {}
+ host: api.scaleway.com
+ remote_addr: ""
+ request_uri: ""
+ body: '{"project_id":"105bdce1-64c0-48ab-899d-868455867ecf","name":"tf-tests-pipeline-name","description":"a description"}'
+ form: {}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/pipelines
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 289
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:09:41.932144710Z","description":"a description","errors":[],"id":"18b8ff40-f82d-406b-aec6-93208d880c24","name":"tf-tests-pipeline-name","project_id":"105bdce1-64c0-48ab-899d-868455867ecf","status":"pending","updated_at":"2024-06-27T14:09:41.932144710Z"}'
+ headers:
+ Content-Length:
+ - "289"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:09:41 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:
+ - 653c854c-509c-4bba-8ff2-f3e6f769b6f8
+ status: 200 OK
+ code: 200
+ duration: 202.485969ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/pipelines/18b8ff40-f82d-406b-aec6-93208d880c24
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 283
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:09:41.932144Z","description":"a description","errors":[],"id":"18b8ff40-f82d-406b-aec6-93208d880c24","name":"tf-tests-pipeline-name","project_id":"105bdce1-64c0-48ab-899d-868455867ecf","status":"pending","updated_at":"2024-06-27T14:09:41.932144Z"}'
+ headers:
+ Content-Length:
+ - "283"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:09:41 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:
+ - 270fc7a5-45e2-4871-a7a1-fa6e8b4c0906
+ status: 200 OK
+ code: 200
+ duration: 44.400765ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/pipelines/18b8ff40-f82d-406b-aec6-93208d880c24
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 283
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:09:41.932144Z","description":"a description","errors":[],"id":"18b8ff40-f82d-406b-aec6-93208d880c24","name":"tf-tests-pipeline-name","project_id":"105bdce1-64c0-48ab-899d-868455867ecf","status":"pending","updated_at":"2024-06-27T14:09:41.932144Z"}'
+ headers:
+ Content-Length:
+ - "283"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:09:42 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:
+ - 89a933b5-1556-40c8-9cf6-570728b7816d
+ status: 200 OK
+ code: 200
+ duration: 43.186892ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/pipelines/18b8ff40-f82d-406b-aec6-93208d880c24
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 283
+ uncompressed: false
+ body: '{"created_at":"2024-06-27T14:09:41.932144Z","description":"a description","errors":[],"id":"18b8ff40-f82d-406b-aec6-93208d880c24","name":"tf-tests-pipeline-name","project_id":"105bdce1-64c0-48ab-899d-868455867ecf","status":"pending","updated_at":"2024-06-27T14:09:41.932144Z"}'
+ headers:
+ Content-Length:
+ - "283"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:09:42 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:
+ - 156ad214-0a98-4bfe-82ad-b86b34bf99bf
+ status: 200 OK
+ code: 200
+ duration: 23.409103ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/pipelines/18b8ff40-f82d-406b-aec6-93208d880c24
+ method: DELETE
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 39
+ uncompressed: false
+ body: '{"message":"PipelineVersion not Found"}'
+ headers:
+ Content-Length:
+ - "39"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 14:09:43 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:
+ - cb334ffe-faf2-424a-a78a-c5955a3521a0
+ status: 404 Not Found
+ code: 404
+ duration: 99.900827ms
diff --git a/internal/services/edgeservices/testdata/edge-services-tls-basic.cassette.yaml b/internal/services/edgeservices/testdata/edge-services-tls-basic.cassette.yaml
new file mode 100644
index 000000000..9da0f409f
--- /dev/null
+++ b/internal/services/edgeservices/testdata/edge-services-tls-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: 95
+ transfer_encoding: []
+ trailer: {}
+ host: api.scaleway.com
+ remote_addr: ""
+ request_uri: ""
+ body: '{"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","secrets":null,"managed_certificate":true}'
+ form: {}
+ headers:
+ Content-Type:
+ - application/json
+ User-Agent:
+ - scaleway-sdk-go/v1.0.0-beta.7+dev (go1.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/tls-stages
+ method: POST
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 285
+ uncompressed: false
+ body: '{"certificate_expires_at":null,"created_at":"2024-06-27T09:20:39.222976571Z","id":"284bc6ef-799e-441d-8939-2e337e8fb60a","managed_certificate":true,"pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","secrets":[],"updated_at":"2024-06-27T09:20:39.222976571Z"}'
+ headers:
+ Content-Length:
+ - "285"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 09:20: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:
+ - e5f882e5-e792-455e-86b1-366970a7f9cd
+ status: 200 OK
+ code: 200
+ duration: 127.728988ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/tls-stages/284bc6ef-799e-441d-8939-2e337e8fb60a
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 279
+ uncompressed: false
+ body: '{"certificate_expires_at":null,"created_at":"2024-06-27T09:20:39.222976Z","id":"284bc6ef-799e-441d-8939-2e337e8fb60a","managed_certificate":true,"pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","secrets":[],"updated_at":"2024-06-27T09:20:39.222976Z"}'
+ headers:
+ Content-Length:
+ - "279"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 09:20: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:
+ - 6cdf3810-8f64-47ef-87fc-0e3994455323
+ status: 200 OK
+ code: 200
+ duration: 60.191283ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/tls-stages/284bc6ef-799e-441d-8939-2e337e8fb60a
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 279
+ uncompressed: false
+ body: '{"certificate_expires_at":null,"created_at":"2024-06-27T09:20:39.222976Z","id":"284bc6ef-799e-441d-8939-2e337e8fb60a","managed_certificate":true,"pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","secrets":[],"updated_at":"2024-06-27T09:20:39.222976Z"}'
+ headers:
+ Content-Length:
+ - "279"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 09:20: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:
+ - be150a0e-0f0e-45ac-b085-38fd64671c6c
+ status: 200 OK
+ code: 200
+ duration: 52.827238ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/tls-stages/284bc6ef-799e-441d-8939-2e337e8fb60a
+ method: GET
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 279
+ uncompressed: false
+ body: '{"certificate_expires_at":null,"created_at":"2024-06-27T09:20:39.222976Z","id":"284bc6ef-799e-441d-8939-2e337e8fb60a","managed_certificate":true,"pipeline_id":null,"project_id":"564aa517-68b0-4fd7-8c8c-d21c4bcdcbd5","secrets":[],"updated_at":"2024-06-27T09:20:39.222976Z"}'
+ headers:
+ Content-Length:
+ - "279"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 09:20: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:
+ - 82d91a9b-37f6-41dd-9981-a50099455fcd
+ status: 200 OK
+ code: 200
+ duration: 54.07179ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/tls-stages/284bc6ef-799e-441d-8939-2e337e8fb60a
+ 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:
+ - Thu, 27 Jun 2024 09:20:40 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:
+ - 53be224e-8bbe-44de-afde-83d0c8b0d290
+ status: 204 No Content
+ code: 204
+ duration: 80.322471ms
+ - 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.22.2; darwin; amd64) terraform-provider/develop terraform/terraform-tests
+ url: https://api.scaleway.com/edge-services/v1alpha1/tls-stages/284bc6ef-799e-441d-8939-2e337e8fb60a
+ method: DELETE
+ response:
+ proto: HTTP/2.0
+ proto_major: 2
+ proto_minor: 0
+ transfer_encoding: []
+ trailer: {}
+ content_length: 31
+ uncompressed: false
+ body: '{"message":"Permission denied"}'
+ headers:
+ Content-Length:
+ - "31"
+ Content-Security-Policy:
+ - default-src 'none'; frame-ancestors 'none'
+ Content-Type:
+ - application/json
+ Date:
+ - Thu, 27 Jun 2024 09:20:40 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:
+ - ddccdfdb-6805-4bed-8f4a-eb98f289bd89
+ status: 403 Forbidden
+ code: 403
+ duration: 36.668511ms
diff --git a/internal/services/edgeservices/testfuncs/checks.go b/internal/services/edgeservices/testfuncs/checks.go
new file mode 100644
index 000000000..c1457f035
--- /dev/null
+++ b/internal/services/edgeservices/testfuncs/checks.go
@@ -0,0 +1,252 @@
+package edgeservicestestfuncs
+
+import (
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
+ edge "github.com/scaleway/scaleway-sdk-go/api/edge_services/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/edgeservices"
+)
+
+func CheckEdgeServicesPipelineDestroy(tt *acctest.TestTools) resource.TestCheckFunc {
+ return func(state *terraform.State) error {
+ for _, rs := range state.RootModule().Resources {
+ if rs.Type != "scaleway_edge_services_pipeline" {
+ continue
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ err := edgeAPI.DeletePipeline(&edge.DeletePipelineRequest{
+ PipelineID: rs.Primary.ID,
+ })
+
+ // If no error resource still exist
+ if err == nil {
+ return fmt.Errorf("pipeline (%s) still exists", rs.Primary.ID)
+ }
+
+ // Unexpected api error we return it
+ if !httperrors.Is404(err) && !httperrors.Is403(err) {
+ return err
+ }
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesBackendDestroy(tt *acctest.TestTools) resource.TestCheckFunc {
+ return func(state *terraform.State) error {
+ for _, rs := range state.RootModule().Resources {
+ if rs.Type != "scaleway_edge_services_backend_stage" {
+ continue
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ err := edgeAPI.DeleteBackendStage(&edge.DeleteBackendStageRequest{
+ BackendStageID: rs.Primary.ID,
+ })
+
+ // If no error resource still exist
+ if err == nil {
+ return fmt.Errorf("backend stage (%s) still exists", rs.Primary.ID)
+ }
+
+ // Unexpected api error we return it
+ if !httperrors.Is404(err) && !httperrors.Is403(err) {
+ return err
+ }
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesDNSDestroy(tt *acctest.TestTools) resource.TestCheckFunc {
+ return func(state *terraform.State) error {
+ for _, rs := range state.RootModule().Resources {
+ if rs.Type != "scaleway_edge_services_dns_stage" {
+ continue
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ err := edgeAPI.DeleteDNSStage(&edge.DeleteDNSStageRequest{
+ DNSStageID: rs.Primary.ID,
+ })
+
+ // If no error resource still exist
+ if err == nil {
+ return fmt.Errorf("DNS stage (%s) still exists", rs.Primary.ID)
+ }
+
+ // Unexpected api error we return it
+ if !httperrors.Is404(err) && !httperrors.Is403(err) {
+ return err
+ }
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesTLSDestroy(tt *acctest.TestTools) resource.TestCheckFunc {
+ return func(state *terraform.State) error {
+ for _, rs := range state.RootModule().Resources {
+ if rs.Type != "scaleway_edge_services_tls_stage" {
+ continue
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ err := edgeAPI.DeleteTLSStage(&edge.DeleteTLSStageRequest{
+ TLSStageID: rs.Primary.ID,
+ })
+
+ // If no error resource still exist
+ if err == nil {
+ return fmt.Errorf("TLS stage (%s) still exists", rs.Primary.ID)
+ }
+
+ // Unexpected api error we return it
+ if !httperrors.Is404(err) && !httperrors.Is403(err) {
+ return err
+ }
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesCacheDestroy(tt *acctest.TestTools) resource.TestCheckFunc {
+ return func(state *terraform.State) error {
+ for _, rs := range state.RootModule().Resources {
+ if rs.Type != "scaleway_edge_services_cache_stage" {
+ continue
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ err := edgeAPI.DeleteCacheStage(&edge.DeleteCacheStageRequest{
+ CacheStageID: rs.Primary.ID,
+ })
+
+ // If no error resource still exist
+ if err == nil {
+ return fmt.Errorf("cache stage (%s) still exists", rs.Primary.ID)
+ }
+
+ // Unexpected api error we return it
+ if !httperrors.Is404(err) && !httperrors.Is403(err) {
+ return err
+ }
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesPipelineExists(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)
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ _, err := edgeAPI.GetPipeline(&edge.GetPipelineRequest{
+ PipelineID: rs.Primary.ID,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesBackendExists(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)
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ _, err := edgeAPI.GetBackendStage(&edge.GetBackendStageRequest{
+ BackendStageID: rs.Primary.ID,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesCacheExists(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)
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ _, err := edgeAPI.GetCacheStage(&edge.GetCacheStageRequest{
+ CacheStageID: rs.Primary.ID,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesDNSExists(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)
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ _, err := edgeAPI.GetDNSStage(&edge.GetDNSStageRequest{
+ DNSStageID: rs.Primary.ID,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+func CheckEdgeServicesTLSExists(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)
+ }
+
+ edgeAPI := edgeservices.NewEdgeServicesAPI(tt.Meta)
+
+ _, err := edgeAPI.GetTLSStage(&edge.GetTLSStageRequest{
+ TLSStageID: rs.Primary.ID,
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
diff --git a/internal/services/edgeservices/testfuncs/sweep.go b/internal/services/edgeservices/testfuncs/sweep.go
new file mode 100644
index 000000000..db5bdbcb0
--- /dev/null
+++ b/internal/services/edgeservices/testfuncs/sweep.go
@@ -0,0 +1,134 @@
+package edgeservicestestfuncs
+
+import (
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ edge "github.com/scaleway/scaleway-sdk-go/api/edge_services/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/services/edgeservices"
+)
+
+func AddTestSweepers() {
+ resource.AddTestSweepers("scaleway_edge_services_pipeline", &resource.Sweeper{
+ Name: "scaleway_edge_services_pipeline",
+ F: testSweepPipeline,
+ })
+ resource.AddTestSweepers("scaleway_edge_services_backend_stage", &resource.Sweeper{
+ Name: "scaleway_edge_services_backend_stage",
+ F: testSweepBackend,
+ })
+ resource.AddTestSweepers("scaleway_edge_services_tls_stage", &resource.Sweeper{
+ Name: "scaleway_edge_services_tls_stage",
+ F: testSweepTLS,
+ })
+ resource.AddTestSweepers("scaleway_edge_services_dns_stage", &resource.Sweeper{
+ Name: "scaleway_edge_services_dns_stage",
+ F: testSweepDNS,
+ })
+ resource.AddTestSweepers("scaleway_edge_services_cache_stage", &resource.Sweeper{
+ Name: "scaleway_edge_services_cache_stage",
+ F: testSweepCache,
+ })
+}
+
+func testSweepPipeline(_ string) error {
+ return acctest.Sweep(func(scwClient *scw.Client) error {
+ edgeAPI := edgeservices.NewEdgeServicesAPI(scwClient)
+
+ listPipelines, err := edgeAPI.ListPipelines(&edge.ListPipelinesRequest{})
+ if err != nil {
+ return fmt.Errorf("failed to list pipelines: %w", err)
+ }
+ for _, pipeline := range listPipelines.Pipelines {
+ err = edgeAPI.DeletePipeline(&edge.DeletePipelineRequest{
+ PipelineID: pipeline.ID,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to delete pipeline: %w", err)
+ }
+ }
+ return nil
+ })
+}
+
+func testSweepDNS(_ string) error {
+ return acctest.Sweep(func(scwClient *scw.Client) error {
+ edgeAPI := edgeservices.NewEdgeServicesAPI(scwClient)
+
+ listDNS, err := edgeAPI.ListDNSStages(&edge.ListDNSStagesRequest{})
+ if err != nil {
+ return fmt.Errorf("failed to list DNS stages: %w", err)
+ }
+ for _, stage := range listDNS.Stages {
+ err = edgeAPI.DeleteDNSStage(&edge.DeleteDNSStageRequest{
+ DNSStageID: stage.ID,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to delete DNS stage: %w", err)
+ }
+ }
+ return nil
+ })
+}
+
+func testSweepTLS(_ string) error {
+ return acctest.Sweep(func(scwClient *scw.Client) error {
+ edgeAPI := edgeservices.NewEdgeServicesAPI(scwClient)
+
+ listTLS, err := edgeAPI.ListTLSStages(&edge.ListTLSStagesRequest{})
+ if err != nil {
+ return fmt.Errorf("failed to list TLS stages: %w", err)
+ }
+ for _, stage := range listTLS.Stages {
+ err = edgeAPI.DeleteTLSStage(&edge.DeleteTLSStageRequest{
+ TLSStageID: stage.ID,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to delete TLS stage: %w", err)
+ }
+ }
+ return nil
+ })
+}
+
+func testSweepCache(_ string) error {
+ return acctest.Sweep(func(scwClient *scw.Client) error {
+ edgeAPI := edgeservices.NewEdgeServicesAPI(scwClient)
+
+ listCaches, err := edgeAPI.ListCacheStages(&edge.ListCacheStagesRequest{})
+ if err != nil {
+ return fmt.Errorf("failed to list cache stages: %w", err)
+ }
+ for _, stage := range listCaches.Stages {
+ err = edgeAPI.DeleteCacheStage(&edge.DeleteCacheStageRequest{
+ CacheStageID: stage.ID,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to delete cache stage: %w", err)
+ }
+ }
+ return nil
+ })
+}
+
+func testSweepBackend(_ string) error {
+ return acctest.Sweep(func(scwClient *scw.Client) error {
+ edgeAPI := edgeservices.NewEdgeServicesAPI(scwClient)
+
+ listBackends, err := edgeAPI.ListBackendStages(&edge.ListBackendStagesRequest{})
+ if err != nil {
+ return fmt.Errorf("failed to list backend stage: %w", err)
+ }
+ for _, stage := range listBackends.Stages {
+ err = edgeAPI.DeleteBackendStage(&edge.DeleteBackendStageRequest{
+ BackendStageID: stage.ID,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to delete backend stage: %w", err)
+ }
+ }
+ return nil
+ })
+}
diff --git a/internal/services/edgeservices/tls_stage.go b/internal/services/edgeservices/tls_stage.go
new file mode 100644
index 000000000..ae9543326
--- /dev/null
+++ b/internal/services/edgeservices/tls_stage.go
@@ -0,0 +1,196 @@
+package edgeservices
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/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 ResourceTLSStage() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: ResourceTLSStageCreate,
+ ReadContext: ResourceTLSStageRead,
+ UpdateContext: ResourceTLSStageUpdate,
+ DeleteContext: ResourceTLSStageDelete,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+ SchemaVersion: 0,
+ Schema: map[string]*schema.Schema{
+ "backend_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The backend stage ID the TLS stage will be linked to",
+ },
+ "cache_stage_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: "The cache stage ID the TLS stage will be linked to",
+ },
+ "managed_certificate": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Computed: true,
+ Description: "Set to true when Scaleway generates and manages a Let's Encrypt certificate for the TLS stage/custom endpoint",
+ },
+ "secrets": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "The TLS secrets",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "secret_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The ID of the Secret",
+ },
+ "region": regional.Schema(),
+ },
+ },
+ },
+ "pipeline_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The pipeline ID the TLS stage belongs to",
+ },
+ "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",
+ },
+ "certificate_expires_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "TThe expiration date of the certificate",
+ },
+ "project_id": account.ProjectIDSchema(),
+ },
+ }
+}
+
+func ResourceTLSStageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api, region, err := NewEdgeServicesAPIWithRegion(d, m)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ tlsStage, err := api.CreateTLSStage(&edgeservices.CreateTLSStageRequest{
+ ProjectID: d.Get("project_id").(string),
+ BackendStageID: types.ExpandStringPtr(d.Get("backend_stage_id").(string)),
+ CacheStageID: types.ExpandStringPtr(d.Get("cache_stage_id").(string)),
+ ManagedCertificate: types.ExpandBoolPtr(d.Get("managed_certificate").(bool)),
+ Secrets: expandTLSSecrets(d.Get("secrets"), region),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId(tlsStage.ID)
+
+ return ResourceTLSStageRead(ctx, d, m)
+}
+
+func ResourceTLSStageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ tlsStage, err := api.GetTLSStage(&edgeservices.GetTLSStageRequest{
+ TLSStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil {
+ if httperrors.Is404(err) {
+ d.SetId("")
+ return nil
+ }
+ return diag.FromErr(err)
+ }
+
+ _ = d.Set("backend_stage_id", types.FlattenStringPtr(tlsStage.BackendStageID))
+ _ = d.Set("cache_stage_id", types.FlattenStringPtr(tlsStage.CacheStageID))
+ _ = d.Set("pipeline_id", types.FlattenStringPtr(tlsStage.PipelineID))
+ _ = d.Set("managed_certificate", tlsStage.ManagedCertificate)
+ _ = d.Set("secrets", flattenTLSSecrets(tlsStage.Secrets))
+ _ = d.Set("certificate_expires_at", types.FlattenTime(tlsStage.CertificateExpiresAt))
+ _ = d.Set("created_at", types.FlattenTime(tlsStage.CreatedAt))
+ _ = d.Set("updated_at", types.FlattenTime(tlsStage.UpdatedAt))
+ _ = d.Set("project_id", tlsStage.ProjectID)
+
+ return nil
+}
+
+func ResourceTLSStageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api, region, err := NewEdgeServicesAPIWithRegion(d, m)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ hasChanged := false
+
+ updateRequest := &edgeservices.UpdateTLSStageRequest{
+ TLSStageID: d.Id(),
+ }
+
+ if d.HasChange("backend_stage_id") {
+ updateRequest.BackendStageID = types.ExpandUpdatedStringPtr(d.Get("backend_stage_id"))
+ hasChanged = true
+ }
+
+ if d.HasChange("cache_stage_id") {
+ updateRequest.CacheStageID = types.ExpandUpdatedStringPtr(d.Get("cache_stage_id"))
+ hasChanged = true
+ }
+
+ if d.HasChange("managed_certificate") {
+ updateRequest.ManagedCertificate = types.ExpandBoolPtr(d.Get("managed_certificate"))
+ hasChanged = true
+ }
+
+ if d.HasChange("secrets") {
+ updateRequest.TLSSecretsConfig = wrapSecretsInConfig(expandTLSSecrets(d.Get("secrets"), region))
+ hasChanged = true
+ }
+
+ if hasChanged {
+ _, err = api.UpdateTLSStage(updateRequest, scw.WithContext(ctx))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ return ResourceTLSStageRead(ctx, d, m)
+}
+
+func ResourceTLSStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+ api := NewEdgeServicesAPI(m)
+
+ err := retry.RetryContext(ctx, defaultEdgeServicesTimeout, func() *retry.RetryError {
+ err := api.DeleteTLSStage(&edgeservices.DeleteTLSStageRequest{
+ TLSStageID: d.Id(),
+ }, scw.WithContext(ctx))
+ if err != nil && !httperrors.Is403(err) {
+ if isStageUsedInPipelineError(err) {
+ return retry.RetryableError(err)
+ }
+ return retry.NonRetryableError(err)
+ }
+ return nil
+ })
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+}
diff --git a/internal/services/edgeservices/tls_stage_test.go b/internal/services/edgeservices/tls_stage_test.go
new file mode 100644
index 000000000..e49cc251f
--- /dev/null
+++ b/internal/services/edgeservices/tls_stage_test.go
@@ -0,0 +1,34 @@
+package edgeservices_test
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
+ edgeservicestestfuncs "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/edgeservices/testfuncs"
+)
+
+func TestAccEdgeServicesTLS_Basic(t *testing.T) {
+ tt := acctest.NewTestTools(t)
+ defer tt.Cleanup()
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { acctest.PreCheck(t) },
+ ProviderFactories: tt.ProviderFactories,
+ CheckDestroy: edgeservicestestfuncs.CheckEdgeServicesTLSDestroy(tt),
+ Steps: []resource.TestStep{
+ {
+ Config: `
+ resource "scaleway_edge_services_tls_stage" "main" {
+ managed_certificate = true
+ }
+ `,
+ Check: resource.ComposeTestCheckFunc(
+ edgeservicestestfuncs.CheckEdgeServicesTLSExists(tt, "scaleway_edge_services_tls_stage.main"),
+ resource.TestCheckResourceAttr("scaleway_edge_services_tls_stage.main", "managed_certificate", "true"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_tls_stage.main", "created_at"),
+ resource.TestCheckResourceAttrSet("scaleway_edge_services_tls_stage.main", "updated_at"),
+ ),
+ },
+ },
+ })
+}
diff --git a/internal/services/edgeservices/types.go b/internal/services/edgeservices/types.go
new file mode 100644
index 000000000..1f4785f13
--- /dev/null
+++ b/internal/services/edgeservices/types.go
@@ -0,0 +1,124 @@
+package edgeservices
+
+import (
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ edge_services "github.com/scaleway/scaleway-sdk-go/api/edge_services/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/types"
+)
+
+func expandS3BackendConfig(raw interface{}) *edge_services.ScalewayS3BackendConfig {
+ if raw == nil || len(raw.([]interface{})) != 1 {
+ return nil
+ }
+ rawMap := raw.([]interface{})[0].(map[string]interface{})
+ return &edge_services.ScalewayS3BackendConfig{
+ BucketName: types.ExpandStringPtr(rawMap["bucket_name"].(string)),
+ BucketRegion: types.ExpandStringPtr(rawMap["bucket_region"].(string)),
+ IsWebsite: types.ExpandBoolPtr(rawMap["is_website"]),
+ }
+}
+
+func flattenS3BackendConfig(s3backend *edge_services.ScalewayS3BackendConfig) []map[string]interface{} {
+ return []map[string]interface{}{
+ {
+ "bucket_name": types.FlattenStringPtr(s3backend.BucketName),
+ "bucket_region": types.FlattenStringPtr(s3backend.BucketRegion),
+ "is_website": types.FlattenBoolPtr(s3backend.IsWebsite),
+ },
+ }
+}
+
+func expandPurge(raw interface{}) []*edge_services.PurgeRequest {
+ if raw == nil {
+ return nil
+ }
+
+ purgeRequests := []*edge_services.PurgeRequest(nil)
+ for _, pr := range raw.(*schema.Set).List() {
+ rawPr := pr.(map[string]interface{})
+ purgeRequest := &edge_services.PurgeRequest{}
+ purgeRequest.PipelineID = rawPr["pipeline_id"].(string)
+ purgeRequest.Assets = types.ExpandStringsPtr(rawPr["assets"])
+ purgeRequest.All = types.ExpandBoolPtr(rawPr["all"])
+
+ purgeRequests = append(purgeRequests, purgeRequest)
+ }
+ return purgeRequests
+}
+
+func expandTLSSecrets(raw interface{}, region scw.Region) []*edge_services.TLSSecret {
+ secrets := []*edge_services.TLSSecret(nil)
+ rawSecrets := raw.([]interface{})
+ for _, rawSecret := range rawSecrets {
+ mapSecret := rawSecret.(map[string]interface{})
+ secret := &edge_services.TLSSecret{
+ SecretID: locality.ExpandID(mapSecret["secret_id"]),
+ Region: region,
+ }
+ secrets = append(secrets, secret)
+ }
+ return secrets
+}
+
+func flattenTLSSecrets(secrets []*edge_services.TLSSecret) interface{} {
+ if len(secrets) == 0 || secrets == nil {
+ return nil
+ }
+
+ secretsI := []map[string]interface{}(nil)
+ for _, secret := range secrets {
+ secretMap := map[string]interface{}{
+ "secret_id": secret.SecretID,
+ "region": secret.Region.String(),
+ }
+ secretsI = append(secretsI, secretMap)
+ }
+ return secretsI
+}
+
+func expandLBBackendConfig(raw interface{}) *edge_services.ScalewayLBBackendConfig {
+ lbConfigs := []*edge_services.ScalewayLB(nil)
+ rawLbConfigs := raw.([]interface{})
+ for _, rawLbConfig := range rawLbConfigs {
+ mapLbConfig := rawLbConfig.(map[string]interface{})
+ lbConfig := &edge_services.ScalewayLB{
+ ID: locality.ExpandID(mapLbConfig["id"]),
+ Zone: scw.Zone(mapLbConfig["zone"].(string)),
+ FrontendID: locality.ExpandID(mapLbConfig["frontend_id"]),
+ IsSsl: types.ExpandBoolPtr(mapLbConfig["is_ssl"]),
+ DomainName: types.ExpandStringPtr(mapLbConfig["domain_name"]),
+ }
+ lbConfigs = append(lbConfigs, lbConfig)
+ }
+
+ return &edge_services.ScalewayLBBackendConfig{
+ LBs: lbConfigs,
+ }
+}
+
+func flattenLBBackendConfig(lbConfigs *edge_services.ScalewayLBBackendConfig) interface{} {
+ if lbConfigs == nil {
+ return nil
+ }
+
+ lbConfigsI := []map[string]interface{}(nil)
+ for _, lbConfig := range lbConfigs.LBs {
+ secretMap := map[string]interface{}{
+ "id": lbConfig.ID,
+ "frontend_id": lbConfig.FrontendID,
+ "is_ssl": types.FlattenBoolPtr(lbConfig.IsSsl),
+ "domain_name": types.FlattenStringPtr(lbConfig.DomainName),
+ "zone": lbConfig.Zone.String(),
+ }
+ lbConfigsI = append(lbConfigsI, secretMap)
+ }
+ return lbConfigsI
+}
+
+func wrapSecretsInConfig(secrets []*edge_services.TLSSecret) *edge_services.TLSSecretsConfig {
+ return &edge_services.TLSSecretsConfig{
+ TLSSecrets: secrets,
+ }
+}
diff --git a/internal/services/edgeservices/waiters.go b/internal/services/edgeservices/waiters.go
new file mode 100644
index 000000000..84bfa4a19
--- /dev/null
+++ b/internal/services/edgeservices/waiters.go
@@ -0,0 +1,44 @@
+package edgeservices
+
+import (
+ "context"
+ "time"
+
+ edgeservices "github.com/scaleway/scaleway-sdk-go/api/edge_services/v1alpha1"
+ "github.com/scaleway/scaleway-sdk-go/scw"
+ "github.com/scaleway/terraform-provider-scaleway/v2/internal/transport"
+)
+
+const (
+ defaultEdgeServicesTimeout = 5 * time.Minute
+)
+
+func waitForPipeline(ctx context.Context, edgeServicesapi *edgeservices.API, id string, timeout time.Duration) (*edgeservices.Pipeline, error) {
+ retryInterval := defaultEdgeServicesTimeout
+ if transport.DefaultWaitRetryInterval != nil {
+ retryInterval = *transport.DefaultWaitRetryInterval
+ }
+
+ pipeline, err := edgeServicesapi.WaitForPipeline(&edgeservices.WaitForPipelineRequest{
+ PipelineID: id,
+ RetryInterval: &retryInterval,
+ Timeout: scw.TimeDurationPtr(timeout),
+ }, scw.WithContext(ctx))
+
+ return pipeline, err
+}
+
+func waitForPurge(ctx context.Context, edgeServicesapi *edgeservices.API, id string, timeout time.Duration) (*edgeservices.PurgeRequest, error) {
+ retryInterval := defaultEdgeServicesTimeout
+ if transport.DefaultWaitRetryInterval != nil {
+ retryInterval = *transport.DefaultWaitRetryInterval
+ }
+
+ purgeRequest, err := edgeServicesapi.WaitForPurgeRequest(&edgeservices.WaitForPurgeRequestRequest{
+ PurgeRequestID: id,
+ RetryInterval: &retryInterval,
+ Timeout: scw.TimeDurationPtr(timeout),
+ }, scw.WithContext(ctx))
+
+ return purgeRequest, err
+}