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 65eac23f9..032e6bb78 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -21,6 +21,7 @@ import ( "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/container" "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/documentdb" "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" @@ -142,6 +143,11 @@ func Provider(config *Config) plugin.ProviderFunc { "scaleway_documentdb_user": documentdb.ResourceUser(), "scaleway_domain_record": domain.ResourceRecord(), "scaleway_domain_zone": domain.ResourceZone(), + "scaleway_edge_services_backend_stage": edgeservices.ResourceEdgeServicesBackendStage(), + "scaleway_edge_services_cache_stage": edgeservices.ResourceEdgeServicesCacheStage(), + "scaleway_edge_services_dns_stage": edgeservices.ResourceEdgeServicesDNSStage(), + "scaleway_edge_services_pipeline": edgeservices.ResourceEdgeServicesPipeline(), + "scaleway_edge_services_tls_stage": edgeservices.ResourceEdgeServicesTLSStage(), "scaleway_flexible_ip": flexibleip.ResourceIP(), "scaleway_flexible_ip_mac_address": flexibleip.ResourceMACAddress(), "scaleway_function": function.ResourceFunction(), diff --git a/internal/services/edgeservices/edge_services_backend_stage.go b/internal/services/edgeservices/edge_services_backend_stage.go new file mode 100644 index 000000000..cba2b513c --- /dev/null +++ b/internal/services/edgeservices/edge_services_backend_stage.go @@ -0,0 +1,144 @@ +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/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" +) + +func ResourceEdgeServicesBackendStage() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceEdgeServicesBackendStageCreate, + ReadContext: ResourceEdgeServicesBackendStageRead, + UpdateContext: ResourceEdgeServicesBackendStageUpdate, + DeleteContext: ResourceEdgeServicesBackendStageDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 0, + Schema: map[string]*schema.Schema{ + "s3_backend_config": { + Type: schema.TypeList, + Optional: true, + 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.", + }, + }, + }, + }, + "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 ResourceEdgeServicesBackendStageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + api := NewEdgeServicesAPI(m) + + backendStage, err := api.CreateBackendStage(&edgeservices.CreateBackendStageRequest{ + ProjectID: d.Get("project_id").(string), + ScalewayS3: expandS3BackendConfig(d.Get("s3_backend_config")), + }, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(backendStage.ID) + + return ResourceEdgeServicesBackendStageRead(ctx, d, m) +} + +func ResourceEdgeServicesBackendStageRead(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)) + + return nil +} + +func ResourceEdgeServicesBackendStageUpdate(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 hasChanged { + _, err := api.UpdateBackendStage(updateRequest, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + } + + return ResourceEdgeServicesBackendStageRead(ctx, d, m) +} + +func ResourceEdgeServicesBackendStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + api := NewEdgeServicesAPI(m) + + err := api.DeleteBackendStage(&edgeservices.DeleteBackendStageRequest{ + BackendStageID: d.Id(), + }, scw.WithContext(ctx)) + if err != nil && !httperrors.Is403(err) { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/edgeservices/edge_services_backend_stage_test.go b/internal/services/edgeservices/edge_services_backend_stage_test.go new file mode 100644 index 000000000..f27ae603d --- /dev/null +++ b/internal/services/edgeservices/edge_services_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/edge_services_cache_stage.go b/internal/services/edgeservices/edge_services_cache_stage.go new file mode 100644 index 000000000..7bb9831b6 --- /dev/null +++ b/internal/services/edgeservices/edge_services_cache_stage.go @@ -0,0 +1,188 @@ +package edgeservices + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "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 ResourceEdgeServicesCacheStage() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceEdgeServicesCacheStageCreate, + ReadContext: ResourceEdgeServicesCacheStageRead, + UpdateContext: ResourceEdgeServicesCacheStageUpdate, + DeleteContext: ResourceEdgeServicesCacheStageDelete, + 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 ResourceEdgeServicesCacheStageCreate(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: 3600}, + }, scw.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(cacheStage.ID) + + return ResourceEdgeServicesCacheStageRead(ctx, d, m) +} + +func ResourceEdgeServicesCacheStageRead(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 ResourceEdgeServicesCacheStageUpdate(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 ResourceEdgeServicesCacheStageRead(ctx, d, m) +} + +func ResourceEdgeServicesCacheStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + api := NewEdgeServicesAPI(m) + + err := api.DeleteCacheStage(&edge_services.DeleteCacheStageRequest{ + CacheStageID: d.Id(), + }, scw.WithContext(ctx)) + if err != nil && !httperrors.Is403(err) { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/edgeservices/edge_services_cache_stage_test.go b/internal/services/edgeservices/edge_services_cache_stage_test.go new file mode 100644 index 000000000..addfc692c --- /dev/null +++ b/internal/services/edgeservices/edge_services_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/edge_services_dns_stage.go b/internal/services/edgeservices/edge_services_dns_stage.go new file mode 100644 index 000000000..9d6fc1b38 --- /dev/null +++ b/internal/services/edgeservices/edge_services_dns_stage.go @@ -0,0 +1,204 @@ +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/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" +) + +func ResourceEdgeServicesDNSStage() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceEdgeServicesDNSStageCreate, + ReadContext: ResourceEdgeServicesDNSStageRead, + UpdateContext: ResourceEdgeServicesDNSStageUpdate, + DeleteContext: ResourceEdgeServicesDNSStageDelete, + 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 ResourceEdgeServicesDNSStageCreate(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 ResourceEdgeServicesDNSStageRead(ctx, d, m) +} + +func ResourceEdgeServicesDNSStageRead(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 ResourceEdgeServicesDNSStageUpdate(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 ResourceEdgeServicesDNSStageRead(ctx, d, m) +} + +func ResourceEdgeServicesDNSStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + api := NewEdgeServicesAPI(m) + + err := api.DeleteDNSStage(&edgeservices.DeleteDNSStageRequest{ + DNSStageID: d.Id(), + }, scw.WithContext(ctx)) + if err != nil && !httperrors.Is403(err) { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/edgeservices/edge_services_dns_stage_test.go b/internal/services/edgeservices/edge_services_dns_stage_test.go new file mode 100644 index 000000000..9eb82f91e --- /dev/null +++ b/internal/services/edgeservices/edge_services_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/edge_services_pipeline.go b/internal/services/edgeservices/edge_services_pipeline.go new file mode 100644 index 000000000..5651b6d0c --- /dev/null +++ b/internal/services/edgeservices/edge_services_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 ResourceEdgeServicesPipeline() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceEdgeServicesPipelineCreate, + ReadContext: ResourceEdgeServicesPipelineRead, + UpdateContext: ResourceEdgeServicesPipelineUpdate, + DeleteContext: ResourceEdgeServicesPipelineDelete, + 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 ResourceEdgeServicesPipelineCreate(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 ResourceEdgeServicesPipelineRead(ctx, d, m) +} + +func ResourceEdgeServicesPipelineRead(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 ResourceEdgeServicesPipelineUpdate(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 ResourceEdgeServicesPipelineRead(ctx, d, m) +} + +func ResourceEdgeServicesPipelineDelete(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/edge_services_pipeline_test.go b/internal/services/edgeservices/edge_services_pipeline_test.go new file mode 100644 index 000000000..8e1398511 --- /dev/null +++ b/internal/services/edgeservices/edge_services_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/edge_services_tls_stage.go b/internal/services/edgeservices/edge_services_tls_stage.go new file mode 100644 index 000000000..5f79ad404 --- /dev/null +++ b/internal/services/edgeservices/edge_services_tls_stage.go @@ -0,0 +1,186 @@ +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/regional" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account" + "github.com/scaleway/terraform-provider-scaleway/v2/internal/types" +) + +func ResourceEdgeServicesTLSStage() *schema.Resource { + return &schema.Resource{ + CreateContext: ResourceEdgeServicesTLSStageCreate, + ReadContext: ResourceEdgeServicesTLSStageRead, + UpdateContext: ResourceEdgeServicesTLSStageUpdate, + DeleteContext: ResourceEdgeServicesTLSStageDelete, + 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 ResourceEdgeServicesTLSStageCreate(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 ResourceEdgeServicesTLSStageRead(ctx, d, m) +} + +func ResourceEdgeServicesTLSStageRead(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 ResourceEdgeServicesTLSStageUpdate(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 ResourceEdgeServicesTLSStageRead(ctx, d, m) +} + +func ResourceEdgeServicesTLSStageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + api := NewEdgeServicesAPI(m) + + err := api.DeleteTLSStage(&edgeservices.DeleteTLSStageRequest{ + TLSStageID: d.Id(), + }, scw.WithContext(ctx)) + if err != nil && !httperrors.Is403(err) { + return diag.FromErr(err) + } + + return nil +} diff --git a/internal/services/edgeservices/edge_services_tls_stage_test.go b/internal/services/edgeservices/edge_services_tls_stage_test.go new file mode 100644 index 000000000..e49cc251f --- /dev/null +++ b/internal/services/edgeservices/edge_services_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/helpers.go b/internal/services/edgeservices/helpers.go new file mode 100644 index 000000000..39309ef41 --- /dev/null +++ b/internal/services/edgeservices/helpers.go @@ -0,0 +1,24 @@ +package edgeservices + +import ( + "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 +} 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: ObjectLockConfigurationNotFoundErrorObject 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: NoSuchCORSConfigurationThe 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: NoSuchLifecycleConfigurationThe 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: ObjectLockConfigurationNotFoundErrorObject 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: NoSuchCORSConfigurationThe 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: NoSuchLifecycleConfigurationThe 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/types.go b/internal/services/edgeservices/types.go new file mode 100644 index 000000000..fe69d21e4 --- /dev/null +++ b/internal/services/edgeservices/types.go @@ -0,0 +1,85 @@ +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 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 +}