From cb77273839e7123ce1caf7b1fe70a1faf5ea03b3 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 15 Apr 2024 15:47:32 -0700 Subject: [PATCH 01/20] Temporarily vendor go-fastly from Image Optimizer default settings API PR --- .../fastly/go-fastly/v9/fastly/errors.go | 4 + .../image_optimizer_default_settings.go | 139 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/errors.go b/vendor/github.com/fastly/go-fastly/v9/fastly/errors.go index 06e1a3761..c622f9380 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/errors.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/errors.go @@ -332,6 +332,10 @@ var ErrMissingCertificateMTLS = NewFieldError("Certificate, MutualAuthentication // requires a "IntegrationID" key, but one was not set. var ErrMissingIntegrationID = NewFieldError("IntegrationID") +// ErrMissingImageOptimizerSettings is an error that is returned when an input struct +// requires one of the optional Image Optimizer default settings, but none are set. +var ErrMissingImageOptimizerDefaultSetting = NewFieldError("ResizeFilter, Webp, WebpQuality, JpegType, JpegQuality, Upscale, AllowVideo").Message("at least one of the available optional fields is required") + // Ensure HTTPError is, in fact, an error. var _ error = (*HTTPError)(nil) diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go new file mode 100644 index 000000000..8e0a396e1 --- /dev/null +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go @@ -0,0 +1,139 @@ +package fastly + +import ( + "fmt" +) + +// ResizeFilter is a base for the different ResizeFilter variants. +type ResizeFilter int64 + +func (r ResizeFilter) String() string { + switch r { + case Lanczos3: + return "lanczos3" + case Lanczos2: + return "lanczos2" + case Bicubic: + return "bicubic" + case Bilinear: + return "bilinear" + case Nearest: + return "nearest" + } + return "lanczos3" // default +} + +const ( + Lanczos3 ResizeFilter = iota + Lanczos2 + Bicubic + Bilinear + Nearest +) + +// ImageOptimizerDefaultSettings represents the returned default settings for Image Optimizer on a given service. +type ImageOptimizerDefaultSettings struct { + // Type of filter to use while resizing an image. + ResizeFilter string `mapstructure:"resize_filter"` + // Whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. + Webp bool `mapstructure:"webp"` + // Default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer + // requests. + WebpQuality int `mapstructure:"webp_quality"` + // Default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. + JpegType string `mapstructure:"jpeg_type"` + // Default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. + JpegQuality int `mapstructure:"jpeg_quality"` + // Whether or not we should allow output images to render at sizes larger than input. + Upscale bool `mapstructure:"upscale"` + // Enables GIF to MP4 transformations on this service. + AllowVideo bool `mapstructure:"allow_video"` +} + +// GetImageOptimizerDefaultSettingsInput is used as input to the +// GetImageOptimizerDefaultSettings function. +type GetImageOptimizerDefaultSettingsInput struct { + // ServiceID is the ID of the service (required). + ServiceID string + // ServiceVersion is the specific configuration version (required). + ServiceVersion int +} + +// UpdateImageOptimizerDefaultSettingsInput is used as input to the +// UpdateImageOptimizerDefaultSettings function. +// +// A minimum of one optional field is required. +type UpdateImageOptimizerDefaultSettingsInput struct { + // ServiceID is the ID of the service (required). + ServiceID string `json:"-"` + // ServiceVersion is the specific configuration version (required). + ServiceVersion int `json:"-"` + // Type of filter to use while resizing an image. + ResizeFilter *ResizeFilter `json:"resize_filter,omitempty"` + // Whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. + Webp *bool `json:"webp,omitempty"` + // Default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer + // requests. + WebpQuality *int `json:"webp_quality,omitempty"` + // Default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. + JpegType *string `json:"jpeg_type,omitempty"` + // Default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. + JpegQuality *int `json:"jpeg_quality,omitempty"` + // Whether or not we should allow output images to render at sizes larger than input. + Upscale *bool `json:"upscale,omitempty"` + // Enables GIF to MP4 transformations on this service. + AllowVideo *bool `json:"allow_video,omitempty"` +} + +// GetImageOptimizerDefaultSettings retrives the current Image Optimizer default settings on a given service version. +func (c *Client) GetImageOptimizerDefaultSettings(i *GetImageOptimizerDefaultSettingsInput) (*ImageOptimizerDefaultSettings, error) { + if i.ServiceID == "" { + return nil, ErrMissingServiceID + } + if i.ServiceVersion == 0 { + return nil, ErrMissingServiceVersion + } + + path := fmt.Sprintf("/service/%s/version/%d/image_optimizer_default_settings", i.ServiceID, i.ServiceVersion) + + resp, err := c.Get(path, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var iods *ImageOptimizerDefaultSettings + if err := decodeBodyMap(resp.Body, &iods); err != nil { + return nil, err + } + + return iods, nil +} + +// UpdateImageOptimizerDefaultSettings changes one or more Image Optimizer default settings on a given service version. +func (c *Client) UpdateImageOptimizerDefaultSettings(i *UpdateImageOptimizerDefaultSettingsInput) (*ImageOptimizerDefaultSettings, error) { + if i.ServiceID == "" { + return nil, ErrMissingServiceID + } + if i.ServiceVersion == 0 { + return nil, ErrMissingServiceVersion + } + if i.ResizeFilter == nil && i.Webp == nil && i.WebpQuality == nil && i.JpegType == nil && i.JpegQuality == nil && i.Upscale == nil && i.AllowVideo == nil { + return nil, ErrMissingImageOptimizerDefaultSetting + } + + path := fmt.Sprintf("/service/%s/version/%d/image_optimizer_default_settings", i.ServiceID, i.ServiceVersion) + + resp, err := c.PatchJSON(path, i, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var iods *ImageOptimizerDefaultSettings + if err := decodeBodyMap(resp.Body, &iods); err != nil { + return nil, err + } + + return iods, nil +} From 2eaeb81b66a21b9757bfb9de70c2d10f9edc71e6 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 15 Apr 2024 15:47:20 -0700 Subject: [PATCH 02/20] Add Image Optimizer default settings API --- ...ervice_image_optimizer_default_settings.go | 208 ++++++++++++++++++ ...e_image_optimizer_default_settings_test.go | 97 ++++++++ fastly/resource_fastly_service_compute.go | 1 + fastly/resource_fastly_service_vcl.go | 1 + 4 files changed, 307 insertions(+) create mode 100644 fastly/block_fastly_service_image_optimizer_default_settings.go create mode 100644 fastly/block_fastly_service_image_optimizer_default_settings_test.go diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go new file mode 100644 index 000000000..5f50b758a --- /dev/null +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -0,0 +1,208 @@ +package fastly + +import ( + "context" + "fmt" + "log" + + gofastly "github.com/fastly/go-fastly/v9/fastly" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +// ProductEnablementServiceAttributeHandler provides a base implementation for ServiceAttributeDefinition. +type ImageOptimizerDefaultSettingsServiceAttributeHandler struct { + *DefaultServiceAttributeHandler +} + +// NewServiceProductEnablement returns a new resource. +func NewServiceImageOptimizerDefaultSettings(sa ServiceMetadata) ServiceAttributeDefinition { + return ToServiceAttributeDefinition(&ImageOptimizerDefaultSettingsServiceAttributeHandler{ + &DefaultServiceAttributeHandler{ + key: "image_optimizer_default_settings", + serviceMetadata: sa, + }, + }) +} + +// Key returns the resource key. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Key() string { + return h.key +} + +// GetSchema returns the resource schema. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *schema.Schema { + attributes := map[string]*schema.Schema{ + "allow_video": { + Type: schema.TypeBool, + Optional: true, + Description: "Enables GIF to MP4 transformations on this service.", + }, + "jpeg_quality": { + Type: schema.TypeInt, + Optional: true, + Description: "The default quality to use with jpeg output. This can be overridden with the \"quality\" parameter on specific image optimizer requests.", + ValidateFunc: validation.IntBetween(1, 100), + }, + "jpeg_type": { + Type: schema.TypeString, + Optional: true, + Description: "The default type of jpeg output to use. This can be overriden with \"format=bjpeg\" and \"format=pjpeg\" on specific image optimizer requests.", + ValidateFunc: validation.StringInSlice([]string{"auto", "baseline", "progressive"}, false), + }, + "resize_filter": { + Type: schema.TypeString, + Optional: true, + Description: "The type of filter to use while resizing an image.", + ValidateFunc: validation.StringInSlice([]string{"lanczos3", "lanczos2", "bicubic", "bilinear", "nearest"}, false), + }, + "upscale": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether or not we should allow output images to render at sizes larger than input.", + }, + "webp": { + Type: schema.TypeBool, + Optional: true, + Description: "Controls whether or not to default to webp output when the client supports it. This is equivalent to adding \"auto=webp\" to all image optimizer requests.", + }, + "webp_quality": { + Type: schema.TypeInt, + Optional: true, + Description: "The default quality to use with webp output. This can be overriden with the second option in the \"quality\" URL parameter on specific image optimizer requests", + ValidateFunc: validation.IntBetween(1, 100), + }, + } + + // NOTE: Min/MaxItems: 1 (to enforce only one image_optimizer_default_settings per service). + // lintignore:S018 + return &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + MinItems: 1, + Elem: &schema.Resource{ + Schema: attributes, + }, + } +} + +// Create creates the resource. +// +// If a user has Image Optimizer enabled, they will always have some default settings. So, creation and updating are synonymous. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Create(c context.Context, d *schema.ResourceData, resource map[string]any, serviceVersion int, conn *gofastly.Client) error { + return h.Update(c, d, resource, resource, serviceVersion, conn) +} + +// Read refreshes the resource. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Read(_ context.Context, d *schema.ResourceData, resource map[string]any, serviceVersion int, conn *gofastly.Client) error { + localState := d.Get(h.Key()).(*schema.Set).List() + + if len(localState) > 0 || d.Get("imported").(bool) || d.Get("force_refresh").(bool) { + serviceID := d.Id() + + log.Printf("[DEBUG] Refreshing Image Optimizer default settings for (%s)", serviceID) + + remoteState, err := conn.GetImageOptimizerDefaultSettings(&gofastly.GetImageOptimizerDefaultSettingsInput{ + ServiceID: serviceID, + ServiceVersion: serviceVersion, + }) + if err != nil { + return err + } + + result := map[string]any{ + "allow_video": remoteState.AllowVideo, + "jpeg_type": remoteState.JpegType, + "jpeg_quality": remoteState.JpegQuality, + "resize_filter": remoteState.ResizeFilter, + "upscale": remoteState.Upscale, + "webp": remoteState.Webp, + "webp_quality": remoteState.WebpQuality, + } + + results := []map[string]any{result} + + // IMPORTANT: Avoid runtime panic "set item just set doesn't exist". + // TF will panic when trying to append an empty map to a TypeSet. + // i.e. a typed nil. + if len(results[0]) > 0 { + if err := d.Set(h.Key(), results); err != nil { + log.Printf("[WARN] Error setting Product Enablement for (%s): %s", d.Id(), err) + return err + } + } + } + + return nil +} + +// Update updates the resource. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context.Context, d *schema.ResourceData, _, modified map[string]any, serviceVersion int, conn *gofastly.Client) error { + serviceID := d.Id() + log.Println("[DEBUG] Update Image Optimizer default settings") + + if len(modified) == 0 { + return nil + } + + apiInput := gofastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: serviceID, + ServiceVersion: serviceVersion, + } + + for key, value := range modified { + switch key { + case "resize_filter": + var resizeFilter gofastly.ResizeFilter + switch value.(string) { + case "lanczos3": + resizeFilter = gofastly.Lanczos3 + case "lanczos2": + resizeFilter = gofastly.Lanczos2 + case "bicubic": + resizeFilter = gofastly.Bicubic + case "bilinear": + resizeFilter = gofastly.Bilinear + case "nearest": + resizeFilter = gofastly.Nearest + default: + return fmt.Errorf("got unexpected resize_filter: %v", value) + } + apiInput.ResizeFilter = &resizeFilter + case "webp": + webp := value.(bool) + apiInput.Webp = &webp + case "webp_quality": + webpQuality := value.(int) + apiInput.WebpQuality = &webpQuality + case "jpeg_type": + jpegType := value.(string) + apiInput.JpegType = &jpegType + case "jpeg_quality": + jpegQuality := value.(int) + apiInput.JpegQuality = &jpegQuality + case "upscale": + upscale := value.(bool) + apiInput.Upscale = &upscale + case "allow_video": + allowVideo := value.(bool) + apiInput.AllowVideo = &allowVideo + default: + return fmt.Errorf("got unexpected image_optimizer_default_settings key: %v", key) + } + } + + if _, err := conn.UpdateImageOptimizerDefaultSettings(&apiInput); err != nil { + return err + } + + return nil +} + +// Delete deletes the resource. +// +// Note: The API does not expose any way to reset default settings, so we don't have much to do here. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Delete(_ context.Context, d *schema.ResourceData, _ map[string]any, _ int, conn *gofastly.Client) error { + return nil +} diff --git a/fastly/block_fastly_service_image_optimizer_default_settings_test.go b/fastly/block_fastly_service_image_optimizer_default_settings_test.go new file mode 100644 index 000000000..3fefab2ef --- /dev/null +++ b/fastly/block_fastly_service_image_optimizer_default_settings_test.go @@ -0,0 +1,97 @@ +package fastly + +import ( + "fmt" + "testing" + + gofastly "github.com/fastly/go-fastly/v9/fastly" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccFastlyServiceImageOptimizerDefaultSettings_basic(t *testing.T) { + var service gofastly.ServiceDetail + serviceName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) + domainName := fmt.Sprintf("fastly-test.tf-%s.com", acctest.RandString(10)) + backendName := fmt.Sprintf("backend-tf-%s", acctest.RandString(10)) + backendAddress := "httpbin.org" + + config := fmt.Sprintf(` + resource "fastly_service_vcl" "foo" { + name = "%s" + + domain { + name = "%s" + comment = "demo" + } + + backend { + address = "%s" + name = "%s" + port = 443 + shield = "amsterdam-nl" + } + + image_optimizer_default_settings { + allow_video = false + jpeg_type = "auto" + jpeg_quality = 85 + resize_filter = "lanczos3" + upscale = false + webp = false + webp_quality = 85 + } + + product_enablement { + image_optimizer = true + } + + force_destroy = true + } + `, serviceName, domainName, backendAddress, backendName) + + // The following backends are what we expect to exist after all our Terraform + // configuration settings have been applied. We expect them to correlate to + // the specific backend definitions in the Terraform configuration. + + b1 := gofastly.Backend{ + Address: gofastly.ToPointer(backendAddress), + Name: gofastly.ToPointer(backendName), + Port: gofastly.ToPointer(443), + Shield: gofastly.ToPointer("amsterdam-nl"), // required for image_optimizer + + // NOTE: The following are defaults applied by the API. + AutoLoadbalance: gofastly.ToPointer(false), + BetweenBytesTimeout: gofastly.ToPointer(10000), + Comment: gofastly.ToPointer(""), + ConnectTimeout: gofastly.ToPointer(1000), + ErrorThreshold: gofastly.ToPointer(0), + FirstByteTimeout: gofastly.ToPointer(15000), + HealthCheck: gofastly.ToPointer(""), + Hostname: gofastly.ToPointer(backendAddress), + MaxConn: gofastly.ToPointer(200), + RequestCondition: gofastly.ToPointer(""), + SSLCheckCert: gofastly.ToPointer(true), + Weight: gofastly.ToPointer(100), + UseSSL: gofastly.ToPointer(false), + } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + ProviderFactories: testAccProviders, + CheckDestroy: testAccCheckServiceVCLDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testAccCheckServiceExists("fastly_service_vcl.foo", &service), + resource.TestCheckResourceAttr("fastly_service_vcl.foo", "name", serviceName), + resource.TestCheckResourceAttr("fastly_service_vcl.foo", "backend.#", "1"), + testAccCheckFastlyServiceVCLBackendAttributes(&service, []*gofastly.Backend{&b1}), + ), + }, + }, + }) +} diff --git a/fastly/resource_fastly_service_compute.go b/fastly/resource_fastly_service_compute.go index 309fc9b52..5d6d16ac7 100644 --- a/fastly/resource_fastly_service_compute.go +++ b/fastly/resource_fastly_service_compute.go @@ -17,6 +17,7 @@ var computeService = &BaseServiceDefinition{ NewServiceDomain(computeAttributes), NewServiceBackend(computeAttributes), NewServiceProductEnablement(computeAttributes), + NewServiceImageOptimizerDefaultSettings(vclAttributes), NewServiceLoggingS3(computeAttributes), NewServiceLoggingPaperTrail(computeAttributes), NewServiceLoggingSumologic(computeAttributes), diff --git a/fastly/resource_fastly_service_vcl.go b/fastly/resource_fastly_service_vcl.go index 5419b20fb..3e4d7262e 100644 --- a/fastly/resource_fastly_service_vcl.go +++ b/fastly/resource_fastly_service_vcl.go @@ -20,6 +20,7 @@ var vclService = &BaseServiceDefinition{ NewServiceHealthCheck(vclAttributes), NewServiceBackend(vclAttributes), NewServiceProductEnablement(vclAttributes), + NewServiceImageOptimizerDefaultSettings(vclAttributes), NewServiceDirector(vclAttributes), NewServiceHeader(vclAttributes), NewServiceGzip(vclAttributes), From a0b9545dd0454aee85df0a8b1f3e7bea8745bd45 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 15 Apr 2024 16:04:16 -0700 Subject: [PATCH 03/20] Generate docs. --- docs/resources/service_compute.md | 15 +++++++++++++++ docs/resources/service_vcl.md | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/docs/resources/service_compute.md b/docs/resources/service_compute.md index 2da76f696..3d244d461 100644 --- a/docs/resources/service_compute.md +++ b/docs/resources/service_compute.md @@ -84,6 +84,7 @@ $ terraform import fastly_service_compute.demo xxxxxxxxxxxxxxxxxxxx@2 - `comment` (String) Description field for the service. Default `Managed by Terraform` - `dictionary` (Block Set) (see [below for nested schema](#nestedblock--dictionary)) - `force_destroy` (Boolean) Services that are active cannot be destroyed. In order to destroy the Service, set `force_destroy` to `true`. Default `false` +- `image_optimizer_default_settings` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--image_optimizer_default_settings)) - `logging_bigquery` (Block Set) (see [below for nested schema](#nestedblock--logging_bigquery)) - `logging_blobstorage` (Block Set) (see [below for nested schema](#nestedblock--logging_blobstorage)) - `logging_cloudfiles` (Block Set) (see [below for nested schema](#nestedblock--logging_cloudfiles)) @@ -187,6 +188,20 @@ Read-Only: - `dictionary_id` (String) The ID of the dictionary + +### Nested Schema for `image_optimizer_default_settings` + +Optional: + +- `allow_video` (Boolean) Enables GIF to MP4 transformations on this service. +- `jpeg_quality` (Number) The default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. +- `jpeg_type` (String) The default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. +- `resize_filter` (String) The type of filter to use while resizing an image. +- `upscale` (Boolean) Whether or not we should allow output images to render at sizes larger than input. +- `webp` (Boolean) Controls whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. +- `webp_quality` (Number) The default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer requests + + ### Nested Schema for `logging_bigquery` diff --git a/docs/resources/service_vcl.md b/docs/resources/service_vcl.md index 85f92e78f..450abc260 100644 --- a/docs/resources/service_vcl.md +++ b/docs/resources/service_vcl.md @@ -260,6 +260,7 @@ $ terraform import fastly_service_vcl.demo xxxxxxxxxxxxxxxxxxxx@2 - `header` (Block Set) (see [below for nested schema](#nestedblock--header)) - `healthcheck` (Block Set) (see [below for nested schema](#nestedblock--healthcheck)) - `http3` (Boolean) Enables support for the HTTP/3 (QUIC) protocol +- `image_optimizer_default_settings` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--image_optimizer_default_settings)) - `logging_bigquery` (Block Set) (see [below for nested schema](#nestedblock--logging_bigquery)) - `logging_blobstorage` (Block Set) (see [below for nested schema](#nestedblock--logging_blobstorage)) - `logging_cloudfiles` (Block Set) (see [below for nested schema](#nestedblock--logging_cloudfiles)) @@ -510,6 +511,20 @@ Optional: - `window` (Number) The number of most recent Healthcheck queries to keep for this Healthcheck. Default `5` + +### Nested Schema for `image_optimizer_default_settings` + +Optional: + +- `allow_video` (Boolean) Enables GIF to MP4 transformations on this service. +- `jpeg_quality` (Number) The default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. +- `jpeg_type` (String) The default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. +- `resize_filter` (String) The type of filter to use while resizing an image. +- `upscale` (Boolean) Whether or not we should allow output images to render at sizes larger than input. +- `webp` (Boolean) Controls whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. +- `webp_quality` (Number) The default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer requests + + ### Nested Schema for `logging_bigquery` From 25ccca58a57573ce3f875a96f4540095bdd79ff8 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:07:19 -0700 Subject: [PATCH 04/20] Handle case where reading image optimizer settings on a service without IO enabled. --- .../block_fastly_service_image_optimizer_default_settings.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index 5f50b758a..89547b961 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -110,6 +110,11 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Read(_ context.Co if err != nil { return err } + // Handle the case where the service has no Image Optimizer default settings configured (for example, if it has never had Image + // Optimizer enabled.) + if remoteState == nil { + return nil + } result := map[string]any{ "allow_video": remoteState.AllowVideo, From 913522b131303c5df76227968a6a249c32014941 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:07:28 -0700 Subject: [PATCH 05/20] Fix "invalid key for element" error caused by missing "name" key --- ...ervice_image_optimizer_default_settings.go | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index 89547b961..ac5752fb4 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -126,16 +126,28 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Read(_ context.Co "webp_quality": remoteState.WebpQuality, } + // The `name` attribute in this resource is used by default as a key for calculating diffs. + // This is handled as part of the internal abstraction logic. + // + // See the call ToServiceAttributeDefinition() inside NewServiceProductEnablement() + // See also the diffing logic: + // - https://github.com/fastly/terraform-provider-fastly/blob/4b9506fba1fd17e2bf760f447cbd8c394bb1e153/fastly/service_crud_attribute_definition.go#L94 + // - https://github.com/fastly/terraform-provider-fastly/blob/4b9506fba1fd17e2bf760f447cbd8c394bb1e153/fastly/diff.go#L108-L117 + // + // Because the name can be set by a user, we first check if the resource + // exists in their state, and if so we'll use the value assigned there. If + // they've not explicitly defined a name in their config, then the default + // value will be returned. + if len(localState) > 0 { + name := localState[0].(map[string]any)["name"].(string) + result["name"] = name + } + results := []map[string]any{result} - // IMPORTANT: Avoid runtime panic "set item just set doesn't exist". - // TF will panic when trying to append an empty map to a TypeSet. - // i.e. a typed nil. - if len(results[0]) > 0 { - if err := d.Set(h.Key(), results); err != nil { - log.Printf("[WARN] Error setting Product Enablement for (%s): %s", d.Id(), err) - return err - } + if err := d.Set(h.Key(), results); err != nil { + log.Printf("[WARN] Error setting Image Optimizer default setting for (%s): %s", d.Id(), err) + return err } } From db46c0f20bedfea589c7b3276dc04270419ab25e Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:08:00 -0700 Subject: [PATCH 06/20] PR cleanup suggestion. --- ...service_image_optimizer_default_settings.go | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index ac5752fb4..a33387344 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -188,23 +188,17 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context. } apiInput.ResizeFilter = &resizeFilter case "webp": - webp := value.(bool) - apiInput.Webp = &webp + apiInput.Webp = gofastly.ToPointer(value.(bool)) case "webp_quality": - webpQuality := value.(int) - apiInput.WebpQuality = &webpQuality + apiInput.WebpQuality = gofastly.ToPointer(value.(int)) case "jpeg_type": - jpegType := value.(string) - apiInput.JpegType = &jpegType + apiInput.JpegType = gofastly.ToPointer(value.(string)) case "jpeg_quality": - jpegQuality := value.(int) - apiInput.JpegQuality = &jpegQuality + apiInput.JpegQuality = gofastly.ToPointer(value.(int)) case "upscale": - upscale := value.(bool) - apiInput.Upscale = &upscale + apiInput.Upscale = gofastly.ToPointer(value.(bool)) case "allow_video": - allowVideo := value.(bool) - apiInput.AllowVideo = &allowVideo + apiInput.AllowVideo = gofastly.ToPointer(value.(bool)) default: return fmt.Errorf("got unexpected image_optimizer_default_settings key: %v", key) } From ec9c0c96772a0c9f1802b8f3f0c648a8bf7cde24 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:09:19 -0700 Subject: [PATCH 07/20] Include default values. I was initially trying to get Terraform to ignore settings that wern't set in the configuration, leaving them at their previously configured value. This seems to be counter to Terraform's design, though, so I've relented & included the current default values for each setting here. It seems like maybe we could have done that for the string values, and non-0 integers, but it seems like a nonstarter for booleans (https://github.com/hashicorp/terraform-plugin-sdk/issues/817), and I didn't want to go against Terraform's design too much. --- .../image_optimizer_default_settings.md | 58 +++++++++++++++++++ ...ervice_image_optimizer_default_settings.go | 17 +++++- 2 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 docs/guides/image_optimizer_default_settings.md diff --git a/docs/guides/image_optimizer_default_settings.md b/docs/guides/image_optimizer_default_settings.md new file mode 100644 index 000000000..7bddb9c0a --- /dev/null +++ b/docs/guides/image_optimizer_default_settings.md @@ -0,0 +1,58 @@ +--- +page_title: image_optimizer_default_settings +subcategory: "Guides" +--- + +## Image Optimizer Default Settings + +The [Product Enablement](https://developer.fastly.com/reference/api/services/image-optimizer-default-settings/) API allows customers to configure default settings for Image Optimizer requests. + +Not all customers are entitled to use these endpoints and so care needs to be given when configuring an `image_optimizer` block in your Terraform configuration. + +Furthermore, even if a customer is entitled to use Image Optimizer, the product must also be enabled with `product_enablement`. + +## Example Usage + +Basic usage: + +```terraform +resource "fastly_service_vcl" "demo" { + name = "demofastly" + + domain { + name = "demo.notexample.com" + comment = "demo" + } + + backend { + address = "127.0.0.1" + name = "localhost" + port = 80 + } + + product_enablement { + image_optimizer = true + } + + image_optimizer_default_settings { + resize_filter = "lanczos3" + webp = false + webp_quality = 85 + jpeg_type = "auto" + jpeg_quality = 85 + upscale = false + allow_video = false + } + + force_destroy = true +} +``` + +All fields in `image_optimizer_default_settings` are optional. + +NOTE: Terraform will set all fields *regardless* of what's specified in the configuration. If a service was previously manually configured, adding this block will cause terraform to overwrite all unset settings with their default values. + +## Delete + +As Image Optimizer default settings will always have some value when a service has image optimizer enabled, deleting the `image_optimizer_default_settings` +block is a no-op. diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index a33387344..ae3644e2c 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -33,54 +33,65 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Key() string { // GetSchema returns the resource schema. func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *schema.Schema { attributes := map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Default: "image_optimizer_default_settings", + Description: "Used by the provider to identify modified settings (changing this value will force the entire block to be deleted, then recreated)", + }, "allow_video": { Type: schema.TypeBool, Optional: true, + Default: false, Description: "Enables GIF to MP4 transformations on this service.", }, "jpeg_quality": { Type: schema.TypeInt, Optional: true, + Default: 85, Description: "The default quality to use with jpeg output. This can be overridden with the \"quality\" parameter on specific image optimizer requests.", ValidateFunc: validation.IntBetween(1, 100), }, "jpeg_type": { Type: schema.TypeString, Optional: true, + Default: "auto", Description: "The default type of jpeg output to use. This can be overriden with \"format=bjpeg\" and \"format=pjpeg\" on specific image optimizer requests.", ValidateFunc: validation.StringInSlice([]string{"auto", "baseline", "progressive"}, false), }, "resize_filter": { Type: schema.TypeString, Optional: true, + Default: "lanczos3", Description: "The type of filter to use while resizing an image.", ValidateFunc: validation.StringInSlice([]string{"lanczos3", "lanczos2", "bicubic", "bilinear", "nearest"}, false), }, "upscale": { Type: schema.TypeBool, Optional: true, + Default: false, Description: "Whether or not we should allow output images to render at sizes larger than input.", }, "webp": { Type: schema.TypeBool, Optional: true, + Default: false, Description: "Controls whether or not to default to webp output when the client supports it. This is equivalent to adding \"auto=webp\" to all image optimizer requests.", }, "webp_quality": { Type: schema.TypeInt, Optional: true, + Default: 85, Description: "The default quality to use with webp output. This can be overriden with the second option in the \"quality\" URL parameter on specific image optimizer requests", ValidateFunc: validation.IntBetween(1, 100), }, } - // NOTE: Min/MaxItems: 1 (to enforce only one image_optimizer_default_settings per service). - // lintignore:S018 + // NOTE: MaxItems: 1 (to enforce only one image_optimizer_default_settings per service). return &schema.Schema{ Type: schema.TypeSet, Optional: true, MaxItems: 1, - MinItems: 1, Elem: &schema.Resource{ Schema: attributes, }, From cb731361c43e1f7ea73f85d9d1c8eb0866071620 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:12:46 -0700 Subject: [PATCH 08/20] Update go-fastly vendored from PR --- .../image_optimizer_default_settings.go | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go index 8e0a396e1..8bac26022 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go @@ -1,6 +1,7 @@ package fastly import ( + "encoding/json" "fmt" ) @@ -34,20 +35,20 @@ const ( // ImageOptimizerDefaultSettings represents the returned default settings for Image Optimizer on a given service. type ImageOptimizerDefaultSettings struct { // Type of filter to use while resizing an image. - ResizeFilter string `mapstructure:"resize_filter"` + ResizeFilter string `json:"resize_filter"` // Whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. - Webp bool `mapstructure:"webp"` + Webp bool `json:"webp"` // Default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer // requests. - WebpQuality int `mapstructure:"webp_quality"` + WebpQuality int `json:"webp_quality"` // Default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. - JpegType string `mapstructure:"jpeg_type"` + JpegType string `json:"jpeg_type"` // Default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. - JpegQuality int `mapstructure:"jpeg_quality"` + JpegQuality int `json:"jpeg_quality"` // Whether or not we should allow output images to render at sizes larger than input. - Upscale bool `mapstructure:"upscale"` + Upscale bool `json:"upscale"` // Enables GIF to MP4 transformations on this service. - AllowVideo bool `mapstructure:"allow_video"` + AllowVideo bool `json:"allow_video"` } // GetImageOptimizerDefaultSettingsInput is used as input to the @@ -86,6 +87,8 @@ type UpdateImageOptimizerDefaultSettingsInput struct { } // GetImageOptimizerDefaultSettings retrives the current Image Optimizer default settings on a given service version. +// +// Returns (nil, nil) if no default settings are set. func (c *Client) GetImageOptimizerDefaultSettings(i *GetImageOptimizerDefaultSettingsInput) (*ImageOptimizerDefaultSettings, error) { if i.ServiceID == "" { return nil, ErrMissingServiceID @@ -98,12 +101,18 @@ func (c *Client) GetImageOptimizerDefaultSettings(i *GetImageOptimizerDefaultSet resp, err := c.Get(path, nil) if err != nil { + if herr, ok := err.(*HTTPError); ok { + if herr.StatusCode == 404 { + // API endpoint returns 404 for services without Image Optimizer settings set. + return nil, nil + } + } return nil, err } defer resp.Body.Close() var iods *ImageOptimizerDefaultSettings - if err := decodeBodyMap(resp.Body, &iods); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&iods); err != nil { return nil, err } @@ -131,7 +140,7 @@ func (c *Client) UpdateImageOptimizerDefaultSettings(i *UpdateImageOptimizerDefa defer resp.Body.Close() var iods *ImageOptimizerDefaultSettings - if err := decodeBodyMap(resp.Body, &iods); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&iods); err != nil { return nil, err } From 17785eab12bcecfa30a2f620d80d77fb14476c55 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:20:56 -0700 Subject: [PATCH 09/20] Fix lints + add debug message. --- ..._service_image_optimizer_default_settings.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index ae3644e2c..215059750 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -33,12 +33,6 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Key() string { // GetSchema returns the resource schema. func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *schema.Schema { attributes := map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Optional: true, - Default: "image_optimizer_default_settings", - Description: "Used by the provider to identify modified settings (changing this value will force the entire block to be deleted, then recreated)", - }, "allow_video": { Type: schema.TypeBool, Optional: true, @@ -59,6 +53,12 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *sche Description: "The default type of jpeg output to use. This can be overriden with \"format=bjpeg\" and \"format=pjpeg\" on specific image optimizer requests.", ValidateFunc: validation.StringInSlice([]string{"auto", "baseline", "progressive"}, false), }, + "name": { + Type: schema.TypeString, + Optional: true, + Default: "image_optimizer_default_settings", + Description: "Used by the provider to identify modified settings (changing this value will force the entire block to be deleted, then recreated)", + }, "resize_filter": { Type: schema.TypeString, Optional: true, @@ -88,6 +88,7 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *sche } // NOTE: MaxItems: 1 (to enforce only one image_optimizer_default_settings per service). + // lintignore:S018 return &schema.Schema{ Type: schema.TypeSet, Optional: true, @@ -210,11 +211,15 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context. apiInput.Upscale = gofastly.ToPointer(value.(bool)) case "allow_video": apiInput.AllowVideo = gofastly.ToPointer(value.(bool)) + case "name": + continue default: return fmt.Errorf("got unexpected image_optimizer_default_settings key: %v", key) } } + log.Printf("[DEBUG] Calling Image Optimizer default settings update API with parameters: %+v", apiInput) + if _, err := conn.UpdateImageOptimizerDefaultSettings(&apiInput); err != nil { return err } From a21b89879628d410727c55697c4f777a5b59aa41 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:58:16 -0700 Subject: [PATCH 10/20] One more vendor update. --- .../image_optimizer_default_settings.go | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go index 8bac26022..0ca0156e0 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go @@ -24,6 +24,10 @@ func (r ResizeFilter) String() string { return "lanczos3" // default } +func (r ResizeFilter) MarshalJSON() ([]byte, error) { + return json.Marshal(r.String()) +} + const ( Lanczos3 ResizeFilter = iota Lanczos2 @@ -32,6 +36,31 @@ const ( Nearest ) +// JpegType is a base for different JpegType variants +type JpegType int64 + +func (r JpegType) String() string { + switch r { + case Auto: + return "auto" + case Baseline: + return "baseline" + case Progressive: + return "progressive" + } + return "auto" // default +} + +func (r JpegType) MarshalJSON() ([]byte, error) { + return json.Marshal(r.String()) +} + +const ( + Auto JpegType = iota + Baseline + Progressive +) + // ImageOptimizerDefaultSettings represents the returned default settings for Image Optimizer on a given service. type ImageOptimizerDefaultSettings struct { // Type of filter to use while resizing an image. @@ -77,7 +106,7 @@ type UpdateImageOptimizerDefaultSettingsInput struct { // requests. WebpQuality *int `json:"webp_quality,omitempty"` // Default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. - JpegType *string `json:"jpeg_type,omitempty"` + JpegType *JpegType `json:"jpeg_type,omitempty"` // Default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. JpegQuality *int `json:"jpeg_quality,omitempty"` // Whether or not we should allow output images to render at sizes larger than input. From 817f5f96b349af528999a0bad38fd237a53ca7e7 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 18 Apr 2024 19:58:19 -0700 Subject: [PATCH 11/20] Update jpeg_type, and with that, finally have a passing test! --- ...stly_service_image_optimizer_default_settings.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index 215059750..a50def92f 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -204,7 +204,18 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context. case "webp_quality": apiInput.WebpQuality = gofastly.ToPointer(value.(int)) case "jpeg_type": - apiInput.JpegType = gofastly.ToPointer(value.(string)) + var jpegType gofastly.JpegType + switch value.(string) { + case "auto": + jpegType = gofastly.Auto + case "baseline": + jpegType = gofastly.Baseline + case "progressive": + jpegType = gofastly.Progressive + default: + return fmt.Errorf("got unexpected jpeg_type: %v", value) + } + apiInput.JpegType = &jpegType case "jpeg_quality": apiInput.JpegQuality = gofastly.ToPointer(value.(int)) case "upscale": From eddada925d0f879e76c5b9aa0e92c243dbe998f2 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 29 Apr 2024 11:32:10 -0700 Subject: [PATCH 12/20] Update vendored code again. --- .../image_optimizer_default_settings.go | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go index 0ca0156e0..6a7ed7d21 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go @@ -29,10 +29,15 @@ func (r ResizeFilter) MarshalJSON() ([]byte, error) { } const ( + // A Lanczos filter with a kernel size of 3. Lanczos filters can detect edges and linear features within an image, providing the best possible reconstruction. Lanczos3 ResizeFilter = iota + // A Lanczos filter with a kernel size of 2. Lanczos2 + // A filter using an average of a 4x4 environment of pixels, weighing the innermost pixels higher. Bicubic + // A filter using an average of a 2x2 environment of pixels. Bilinear + // A filter using the value of nearby translated pixel values. Preserves hard edges. Nearest ) @@ -56,23 +61,25 @@ func (r JpegType) MarshalJSON() ([]byte, error) { } const ( + // Match the input JPEG type, or baseline if transforming from a non-JPEG input. Auto JpegType = iota + // Output baseline JPEG images Baseline + // Output progressive JPEG images Progressive ) -// ImageOptimizerDefaultSettings represents the returned default settings for Image Optimizer on a given service. +// ImageOptimizerDefaultSettings represents the returned Image Optimizer default settings for a given service. type ImageOptimizerDefaultSettings struct { - // Type of filter to use while resizing an image. + // The type of filter to use while resizing an image. ResizeFilter string `json:"resize_filter"` - // Whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. + // Controls whether or not to default to WebP output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. Webp bool `json:"webp"` - // Default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer - // requests. + // The default quality to use with WebP output. This can be overridden with the second option in the "quality" URL parameter on specific image optimizer requests. WebpQuality int `json:"webp_quality"` - // Default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. + // The default type of JPEG output to use. This can be overridden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. JpegType string `json:"jpeg_type"` - // Default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. + // The default quality to use with JPEG output. This can be overridden with the "quality" parameter on specific image optimizer requests. JpegQuality int `json:"jpeg_quality"` // Whether or not we should allow output images to render at sizes larger than input. Upscale bool `json:"upscale"` @@ -98,16 +105,15 @@ type UpdateImageOptimizerDefaultSettingsInput struct { ServiceID string `json:"-"` // ServiceVersion is the specific configuration version (required). ServiceVersion int `json:"-"` - // Type of filter to use while resizing an image. + // The type of filter to use while resizing an image. ResizeFilter *ResizeFilter `json:"resize_filter,omitempty"` - // Whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. + // Controls whether or not to default to WebP output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. Webp *bool `json:"webp,omitempty"` - // Default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer - // requests. + // The default quality to use with WebP output. This can be overridden with the second option in the "quality" URL parameter on specific image optimizer requests. WebpQuality *int `json:"webp_quality,omitempty"` - // Default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. + // The default type of JPEG output to use. This can be overridden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. JpegType *JpegType `json:"jpeg_type,omitempty"` - // Default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. + // The default quality to use with JPEG output. This can be overridden with the "quality" parameter on specific image optimizer requests. JpegQuality *int `json:"jpeg_quality,omitempty"` // Whether or not we should allow output images to render at sizes larger than input. Upscale *bool `json:"upscale,omitempty"` @@ -148,7 +154,11 @@ func (c *Client) GetImageOptimizerDefaultSettings(i *GetImageOptimizerDefaultSet return iods, nil } -// UpdateImageOptimizerDefaultSettings changes one or more Image Optimizer default settings on a given service version. +// UpdateImageOptimizerDefaultSettings Update one or more default settings. +// +// A minimum of one non-nil property is required. +// +// Returns the new Image Optimizer default settings. func (c *Client) UpdateImageOptimizerDefaultSettings(i *UpdateImageOptimizerDefaultSettingsInput) (*ImageOptimizerDefaultSettings, error) { if i.ServiceID == "" { return nil, ErrMissingServiceID From aef2f4cae120e6710ebdaf717ad37398cde98a63 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 29 Apr 2024 11:54:40 -0700 Subject: [PATCH 13/20] Update field documentation. Part of this is updating field with descriptions from the final api-documentation PR. The other part is just my messing with stuff to try to make it look better. --- .../image_optimizer_default_settings.md | 11 +++++-- ...ervice_image_optimizer_default_settings.go | 32 ++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/guides/image_optimizer_default_settings.md b/docs/guides/image_optimizer_default_settings.md index 7bddb9c0a..ca0efe14a 100644 --- a/docs/guides/image_optimizer_default_settings.md +++ b/docs/guides/image_optimizer_default_settings.md @@ -5,11 +5,16 @@ subcategory: "Guides" ## Image Optimizer Default Settings -The [Product Enablement](https://developer.fastly.com/reference/api/services/image-optimizer-default-settings/) API allows customers to configure default settings for Image Optimizer requests. +[Fastly Image Optimizer](https://docs.fastly.com/products/image-optimizer) (Fastly IO) is an [image optimization](https://www.fastly.com/learning/what-is-image-optimization) service that manipulates and transforms your images in real time and caches optimized versions of them. + +Fastly Image Optimizer supports a variety of image formats and applies specific settings to all images by default. These can be controlled with this API or the [web interface](https://docs.fastly.com/en/guides/about-fastly-image-optimizer#configuring-default-image-settings). Changes to other image settings, including most image transformations, require using query string parameters on individual requests. + +The [Image Optimizer default settings](https://developer.fastly.com/reference/api/services/image-optimizer-default-settings/) API allows customers to configure +default settings for Image Optimizer requests, configuring the way images are optimized when not overridden by URL parameters on specific requests. Not all customers are entitled to use these endpoints and so care needs to be given when configuring an `image_optimizer` block in your Terraform configuration. -Furthermore, even if a customer is entitled to use Image Optimizer, the product must also be enabled with `product_enablement`. +Image Optimizer must also be enabled on the specific service. This can be achieved in terraform with the `product_enablement` block. ## Example Usage @@ -50,7 +55,7 @@ resource "fastly_service_vcl" "demo" { All fields in `image_optimizer_default_settings` are optional. -NOTE: Terraform will set all fields *regardless* of what's specified in the configuration. If a service was previously manually configured, adding this block will cause terraform to overwrite all unset settings with their default values. +NOTE: When added, `image_optimizer_default_settings` will always set all default settings. This will replace any settings previously changed in the UI or API. ## Delete diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index a50def92f..bb22cba5b 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -43,27 +43,35 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *sche Type: schema.TypeInt, Optional: true, Default: 85, - Description: "The default quality to use with jpeg output. This can be overridden with the \"quality\" parameter on specific image optimizer requests.", + Description: "The default quality to use with JPEG output. This can be overridden with the \"quality\" parameter on specific image optimizer requests.", ValidateFunc: validation.IntBetween(1, 100), }, "jpeg_type": { - Type: schema.TypeString, - Optional: true, - Default: "auto", - Description: "The default type of jpeg output to use. This can be overriden with \"format=bjpeg\" and \"format=pjpeg\" on specific image optimizer requests.", + Type: schema.TypeString, + Optional: true, + Default: "auto", + Description: "The default type of JPEG output to use. This can be overridden with \"format=bjpeg\" and \"format=pjpeg\" on specific image optimizer requests. Valid values are `auto`, `baseline` and `progressive`." + ` + - auto: Match the input JPEG type, or baseline if transforming from a non-JPEG input. + - baseline: Output baseline JPEG images + - progressive: Output progressive JPEG images`, ValidateFunc: validation.StringInSlice([]string{"auto", "baseline", "progressive"}, false), }, "name": { Type: schema.TypeString, Optional: true, Default: "image_optimizer_default_settings", - Description: "Used by the provider to identify modified settings (changing this value will force the entire block to be deleted, then recreated)", + Description: "Used by the provider to identify modified settings. Changing this value will force the entire block to be deleted, then recreated.", }, "resize_filter": { - Type: schema.TypeString, - Optional: true, - Default: "lanczos3", - Description: "The type of filter to use while resizing an image.", + Type: schema.TypeString, + Optional: true, + Default: "lanczos3", + Description: "The type of filter to use while resizing an image. Valid values are `lanczos3`, `lanczos2`, `bicubic`, `bilinear` and `nearest`." + ` + - lanczos3: A Lanczos filter with a kernel size of 3. Lanczos filters can detect edges and linear features within an image, providing the best possible reconstruction. + - lanczos2: A Lanczos filter with a kernel size of 2. + - bicubic: A filter using an average of a 4x4 environment of pixels, weighing the innermost pixels higher. + - bilinear: A filter using an average of a 2x2 environment of pixels. + - nearest: A filter using the value of nearby translated pixel values. Preserves hard edges.`, ValidateFunc: validation.StringInSlice([]string{"lanczos3", "lanczos2", "bicubic", "bilinear", "nearest"}, false), }, "upscale": { @@ -76,13 +84,13 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) GetSchema() *sche Type: schema.TypeBool, Optional: true, Default: false, - Description: "Controls whether or not to default to webp output when the client supports it. This is equivalent to adding \"auto=webp\" to all image optimizer requests.", + Description: "Controls whether or not to default to WebP output when the client supports it. This is equivalent to adding \"auto=webp\" to all image optimizer requests.", }, "webp_quality": { Type: schema.TypeInt, Optional: true, Default: 85, - Description: "The default quality to use with webp output. This can be overriden with the second option in the \"quality\" URL parameter on specific image optimizer requests", + Description: "The default quality to use with WebP output. This can be overridden with the second option in the \"quality\" URL parameter on specific image optimizer requests.", ValidateFunc: validation.IntBetween(1, 100), }, } From 2a336048ae5324d23119af83b6e58e7a7effde15 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 29 Apr 2024 11:56:28 -0700 Subject: [PATCH 14/20] Update generated docs (also, move image_optimizer_default_settings guide from docs to templates) --- docs/resources/service_compute.md | 19 ++++-- docs/resources/service_vcl.md | 19 ++++-- .../image_optimizer_default_settings.md | 63 +++++++++++++++++++ 3 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 templates/guides/image_optimizer_default_settings.md diff --git a/docs/resources/service_compute.md b/docs/resources/service_compute.md index 3d244d461..a601edf40 100644 --- a/docs/resources/service_compute.md +++ b/docs/resources/service_compute.md @@ -194,12 +194,21 @@ Read-Only: Optional: - `allow_video` (Boolean) Enables GIF to MP4 transformations on this service. -- `jpeg_quality` (Number) The default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. -- `jpeg_type` (String) The default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. -- `resize_filter` (String) The type of filter to use while resizing an image. +- `jpeg_quality` (Number) The default quality to use with JPEG output. This can be overridden with the "quality" parameter on specific image optimizer requests. +- `jpeg_type` (String) The default type of JPEG output to use. This can be overridden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. Valid values are `auto`, `baseline` and `progressive`. + - auto: Match the input JPEG type, or baseline if transforming from a non-JPEG input. + - baseline: Output baseline JPEG images + - progressive: Output progressive JPEG images +- `name` (String) Used by the provider to identify modified settings. Changing this value will force the entire block to be deleted, then recreated. +- `resize_filter` (String) The type of filter to use while resizing an image. Valid values are `lanczos3`, `lanczos2`, `bicubic`, `bilinear` and `nearest`. + - lanczos3: A Lanczos filter with a kernel size of 3. Lanczos filters can detect edges and linear features within an image, providing the best possible reconstruction. + - lanczos2: A Lanczos filter with a kernel size of 2. + - bicubic: A filter using an average of a 4x4 environment of pixels, weighing the innermost pixels higher. + - bilinear: A filter using an average of a 2x2 environment of pixels. + - nearest: A filter using the value of nearby translated pixel values. Preserves hard edges. - `upscale` (Boolean) Whether or not we should allow output images to render at sizes larger than input. -- `webp` (Boolean) Controls whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. -- `webp_quality` (Number) The default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer requests +- `webp` (Boolean) Controls whether or not to default to WebP output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. +- `webp_quality` (Number) The default quality to use with WebP output. This can be overridden with the second option in the "quality" URL parameter on specific image optimizer requests. diff --git a/docs/resources/service_vcl.md b/docs/resources/service_vcl.md index 450abc260..a91ed3a42 100644 --- a/docs/resources/service_vcl.md +++ b/docs/resources/service_vcl.md @@ -517,12 +517,21 @@ Optional: Optional: - `allow_video` (Boolean) Enables GIF to MP4 transformations on this service. -- `jpeg_quality` (Number) The default quality to use with jpeg output. This can be overridden with the "quality" parameter on specific image optimizer requests. -- `jpeg_type` (String) The default type of jpeg output to use. This can be overriden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. -- `resize_filter` (String) The type of filter to use while resizing an image. +- `jpeg_quality` (Number) The default quality to use with JPEG output. This can be overridden with the "quality" parameter on specific image optimizer requests. +- `jpeg_type` (String) The default type of JPEG output to use. This can be overridden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. Valid values are `auto`, `baseline` and `progressive`. + - auto: Match the input JPEG type, or baseline if transforming from a non-JPEG input. + - baseline: Output baseline JPEG images + - progressive: Output progressive JPEG images +- `name` (String) Used by the provider to identify modified settings. Changing this value will force the entire block to be deleted, then recreated. +- `resize_filter` (String) The type of filter to use while resizing an image. Valid values are `lanczos3`, `lanczos2`, `bicubic`, `bilinear` and `nearest`. + - lanczos3: A Lanczos filter with a kernel size of 3. Lanczos filters can detect edges and linear features within an image, providing the best possible reconstruction. + - lanczos2: A Lanczos filter with a kernel size of 2. + - bicubic: A filter using an average of a 4x4 environment of pixels, weighing the innermost pixels higher. + - bilinear: A filter using an average of a 2x2 environment of pixels. + - nearest: A filter using the value of nearby translated pixel values. Preserves hard edges. - `upscale` (Boolean) Whether or not we should allow output images to render at sizes larger than input. -- `webp` (Boolean) Controls whether or not to default to webp output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. -- `webp_quality` (Number) The default quality to use with webp output. This can be overriden with the second option in the "quality" URL parameter on specific image optimizer requests +- `webp` (Boolean) Controls whether or not to default to WebP output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. +- `webp_quality` (Number) The default quality to use with WebP output. This can be overridden with the second option in the "quality" URL parameter on specific image optimizer requests. diff --git a/templates/guides/image_optimizer_default_settings.md b/templates/guides/image_optimizer_default_settings.md new file mode 100644 index 000000000..ca0efe14a --- /dev/null +++ b/templates/guides/image_optimizer_default_settings.md @@ -0,0 +1,63 @@ +--- +page_title: image_optimizer_default_settings +subcategory: "Guides" +--- + +## Image Optimizer Default Settings + +[Fastly Image Optimizer](https://docs.fastly.com/products/image-optimizer) (Fastly IO) is an [image optimization](https://www.fastly.com/learning/what-is-image-optimization) service that manipulates and transforms your images in real time and caches optimized versions of them. + +Fastly Image Optimizer supports a variety of image formats and applies specific settings to all images by default. These can be controlled with this API or the [web interface](https://docs.fastly.com/en/guides/about-fastly-image-optimizer#configuring-default-image-settings). Changes to other image settings, including most image transformations, require using query string parameters on individual requests. + +The [Image Optimizer default settings](https://developer.fastly.com/reference/api/services/image-optimizer-default-settings/) API allows customers to configure +default settings for Image Optimizer requests, configuring the way images are optimized when not overridden by URL parameters on specific requests. + +Not all customers are entitled to use these endpoints and so care needs to be given when configuring an `image_optimizer` block in your Terraform configuration. + +Image Optimizer must also be enabled on the specific service. This can be achieved in terraform with the `product_enablement` block. + +## Example Usage + +Basic usage: + +```terraform +resource "fastly_service_vcl" "demo" { + name = "demofastly" + + domain { + name = "demo.notexample.com" + comment = "demo" + } + + backend { + address = "127.0.0.1" + name = "localhost" + port = 80 + } + + product_enablement { + image_optimizer = true + } + + image_optimizer_default_settings { + resize_filter = "lanczos3" + webp = false + webp_quality = 85 + jpeg_type = "auto" + jpeg_quality = 85 + upscale = false + allow_video = false + } + + force_destroy = true +} +``` + +All fields in `image_optimizer_default_settings` are optional. + +NOTE: When added, `image_optimizer_default_settings` will always set all default settings. This will replace any settings previously changed in the UI or API. + +## Delete + +As Image Optimizer default settings will always have some value when a service has image optimizer enabled, deleting the `image_optimizer_default_settings` +block is a no-op. From 60ba6efa91e8e1b8a270ed1ec443ac6c470d4218 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Mon, 29 Apr 2024 12:16:32 -0700 Subject: [PATCH 15/20] Change Delete so it resets all settings to default. --- .../image_optimizer_default_settings.md | 12 +-- ...ervice_image_optimizer_default_settings.go | 86 ++++++++++++++++++- .../image_optimizer_default_settings.md | 12 +-- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/docs/guides/image_optimizer_default_settings.md b/docs/guides/image_optimizer_default_settings.md index ca0efe14a..4dbd636d3 100644 --- a/docs/guides/image_optimizer_default_settings.md +++ b/docs/guides/image_optimizer_default_settings.md @@ -12,9 +12,7 @@ Fastly Image Optimizer supports a variety of image formats and applies specific The [Image Optimizer default settings](https://developer.fastly.com/reference/api/services/image-optimizer-default-settings/) API allows customers to configure default settings for Image Optimizer requests, configuring the way images are optimized when not overridden by URL parameters on specific requests. -Not all customers are entitled to use these endpoints and so care needs to be given when configuring an `image_optimizer` block in your Terraform configuration. - -Image Optimizer must also be enabled on the specific service. This can be achieved in terraform with the `product_enablement` block. +The service must have the Image Optimizer product enabled using the Product Enablement API, UI, or Terraform block to use the `image_optimizer` block. ## Example Usage @@ -59,5 +57,9 @@ NOTE: When added, `image_optimizer_default_settings` will always set all default ## Delete -As Image Optimizer default settings will always have some value when a service has image optimizer enabled, deleting the `image_optimizer_default_settings` -block is a no-op. +Deleting the resource will reset all Image Optimizer default settings to their default values. + +If deleting the resource errors due to Image Optimizer no longer being enabled on the service, then this error will be ignored. + +When Image Optimizer is next re-enabled on a service, that service's Image Optimizer default settings will be reset - so a disabled service effectively already +has deleted/default Image Optimizer default settings. diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index bb22cba5b..bb5002de3 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "log" + "net/http" + "strings" gofastly "github.com/fastly/go-fastly/v9/fastly" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -248,7 +250,87 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context. // Delete deletes the resource. // -// Note: The API does not expose any way to reset default settings, so we don't have much to do here. -func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Delete(_ context.Context, d *schema.ResourceData, _ map[string]any, _ int, conn *gofastly.Client) error { +// This resets Image Optimizer default settings to their defaults, to make it possible to easily undo any effect this block had. +// +// This assumes the service wasn't modified with the UI or any other non-terraform method. Given terraform's regular mode of operating within the world is to +// assume its in control of everything, I think that's quite a reasonable assumption. +func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Delete(_ context.Context, d *schema.ResourceData, resource map[string]any, serviceVersion int, conn *gofastly.Client) error { + serviceID := d.Id() + log.Println("[DEBUG] Update Image Optimizer default settings") + + apiInput := gofastly.UpdateImageOptimizerDefaultSettingsInput{ + ServiceID: serviceID, + ServiceVersion: serviceVersion, + } + + for key, value := range resource { + switch key { + case "resize_filter": + var resizeFilter gofastly.ResizeFilter + switch value.(string) { + case "lanczos3": + resizeFilter = gofastly.Lanczos3 + case "lanczos2": + resizeFilter = gofastly.Lanczos2 + case "bicubic": + resizeFilter = gofastly.Bicubic + case "bilinear": + resizeFilter = gofastly.Bilinear + case "nearest": + resizeFilter = gofastly.Nearest + default: + return fmt.Errorf("got unexpected resize_filter: %v", value) + } + apiInput.ResizeFilter = &resizeFilter + case "webp": + apiInput.Webp = gofastly.ToPointer(value.(bool)) + case "webp_quality": + apiInput.WebpQuality = gofastly.ToPointer(value.(int)) + case "jpeg_type": + var jpegType gofastly.JpegType + switch value.(string) { + case "auto": + jpegType = gofastly.Auto + case "baseline": + jpegType = gofastly.Baseline + case "progressive": + jpegType = gofastly.Progressive + default: + return fmt.Errorf("got unexpected jpeg_type: %v", value) + } + apiInput.JpegType = &jpegType + case "jpeg_quality": + apiInput.JpegQuality = gofastly.ToPointer(value.(int)) + case "upscale": + apiInput.Upscale = gofastly.ToPointer(value.(bool)) + case "allow_video": + apiInput.AllowVideo = gofastly.ToPointer(value.(bool)) + case "name": + continue + default: + return fmt.Errorf("got unexpected image_optimizer_default_settings key: %v", key) + } + } + + log.Printf("[DEBUG] Calling Image Optimizer default settings update API with parameters: %+v", apiInput) + + if _, err := conn.UpdateImageOptimizerDefaultSettings(&apiInput); err != nil { + // inspect the error type for a title that has a message indicating the user cannot call the API because they do not have Image Optimizer + // enabled. For these users we want to skip the error so that we can allow them to clean up their Terraform state. (also, because the Image Optimizer + // default settings for services with Image Optimizer are effectively cleared by disabling Image Optimizer.) + if he, ok := err.(*gofastly.HTTPError); ok { + if he.StatusCode == http.StatusBadRequest { + for _, e := range he.Errors { + if strings.Contains(e.Detail, "Image Optimizer is not enabled on this service") { + return nil + } + } + } + } + + return err + + } + return nil } diff --git a/templates/guides/image_optimizer_default_settings.md b/templates/guides/image_optimizer_default_settings.md index ca0efe14a..4dbd636d3 100644 --- a/templates/guides/image_optimizer_default_settings.md +++ b/templates/guides/image_optimizer_default_settings.md @@ -12,9 +12,7 @@ Fastly Image Optimizer supports a variety of image formats and applies specific The [Image Optimizer default settings](https://developer.fastly.com/reference/api/services/image-optimizer-default-settings/) API allows customers to configure default settings for Image Optimizer requests, configuring the way images are optimized when not overridden by URL parameters on specific requests. -Not all customers are entitled to use these endpoints and so care needs to be given when configuring an `image_optimizer` block in your Terraform configuration. - -Image Optimizer must also be enabled on the specific service. This can be achieved in terraform with the `product_enablement` block. +The service must have the Image Optimizer product enabled using the Product Enablement API, UI, or Terraform block to use the `image_optimizer` block. ## Example Usage @@ -59,5 +57,9 @@ NOTE: When added, `image_optimizer_default_settings` will always set all default ## Delete -As Image Optimizer default settings will always have some value when a service has image optimizer enabled, deleting the `image_optimizer_default_settings` -block is a no-op. +Deleting the resource will reset all Image Optimizer default settings to their default values. + +If deleting the resource errors due to Image Optimizer no longer being enabled on the service, then this error will be ignored. + +When Image Optimizer is next re-enabled on a service, that service's Image Optimizer default settings will be reset - so a disabled service effectively already +has deleted/default Image Optimizer default settings. From b90906beabb5e4a52e6cb94e866e5a2a164b83a0 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Thu, 9 May 2024 12:48:57 -0700 Subject: [PATCH 16/20] Overhaul Image Optimizer default settings test. --- ...e_image_optimizer_default_settings_test.go | 154 +++++++++++------- 1 file changed, 97 insertions(+), 57 deletions(-) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings_test.go b/fastly/block_fastly_service_image_optimizer_default_settings_test.go index 3fefab2ef..c181f2309 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings_test.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings_test.go @@ -2,11 +2,13 @@ package fastly import ( "fmt" + "reflect" "testing" gofastly "github.com/fastly/go-fastly/v9/fastly" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccFastlyServiceImageOptimizerDefaultSettings_basic(t *testing.T) { @@ -16,64 +18,44 @@ func TestAccFastlyServiceImageOptimizerDefaultSettings_basic(t *testing.T) { backendName := fmt.Sprintf("backend-tf-%s", acctest.RandString(10)) backendAddress := "httpbin.org" - config := fmt.Sprintf(` - resource "fastly_service_vcl" "foo" { - name = "%s" + block1 := ` + resize_filter = "lanczos2" + webp = true + webp_quality = 100 + jpeg_type = "progressive" + jpeg_quality = 100 + upscale = true + allow_video = false + ` - domain { - name = "%s" - comment = "demo" + default_settings1 := gofastly.ImageOptimizerDefaultSettings{ + ResizeFilter: "lanczos2", + Webp: true, + WebpQuality: 100, + JpegType: "progressive", + JpegQuality: 100, + Upscale: true, + AllowVideo: false, } - backend { - address = "%s" - name = "%s" - port = 443 - shield = "amsterdam-nl" - } - - image_optimizer_default_settings { - allow_video = false - jpeg_type = "auto" - jpeg_quality = 85 - resize_filter = "lanczos3" - upscale = false - webp = false - webp_quality = 85 - } + block2 := ` + resize_filter = "bicubic" + webp = false + webp_quality = 30 + jpeg_type = "baseline" + jpeg_quality = 20 + upscale = true + allow_video = true + ` - product_enablement { - image_optimizer = true - } - - force_destroy = true - } - `, serviceName, domainName, backendAddress, backendName) - - // The following backends are what we expect to exist after all our Terraform - // configuration settings have been applied. We expect them to correlate to - // the specific backend definitions in the Terraform configuration. - - b1 := gofastly.Backend{ - Address: gofastly.ToPointer(backendAddress), - Name: gofastly.ToPointer(backendName), - Port: gofastly.ToPointer(443), - Shield: gofastly.ToPointer("amsterdam-nl"), // required for image_optimizer - - // NOTE: The following are defaults applied by the API. - AutoLoadbalance: gofastly.ToPointer(false), - BetweenBytesTimeout: gofastly.ToPointer(10000), - Comment: gofastly.ToPointer(""), - ConnectTimeout: gofastly.ToPointer(1000), - ErrorThreshold: gofastly.ToPointer(0), - FirstByteTimeout: gofastly.ToPointer(15000), - HealthCheck: gofastly.ToPointer(""), - Hostname: gofastly.ToPointer(backendAddress), - MaxConn: gofastly.ToPointer(200), - RequestCondition: gofastly.ToPointer(""), - SSLCheckCert: gofastly.ToPointer(true), - Weight: gofastly.ToPointer(100), - UseSSL: gofastly.ToPointer(false), + def_settings2 := gofastly.ImageOptimizerDefaultSettings{ + ResizeFilter: "bicubic", + Webp: false, + WebpQuality: 30, + JpegType: "baseline", + JpegQuality: 20, + Upscale: true, + AllowVideo: true, } resource.ParallelTest(t, resource.TestCase{ @@ -84,14 +66,72 @@ func TestAccFastlyServiceImageOptimizerDefaultSettings_basic(t *testing.T) { CheckDestroy: testAccCheckServiceVCLDestroy, Steps: []resource.TestStep{ { - Config: config, + Config: testAccImageOptimizerDefaultSettingsVCLConfig(serviceName, domainName, backendAddress, backendName, block1), + Check: resource.ComposeTestCheckFunc( + testAccCheckServiceExists("fastly_service_vcl.foo", &service), + resource.TestCheckResourceAttr("fastly_service_vcl.foo", "name", serviceName), + resource.TestCheckResourceAttr("fastly_service_vcl.foo", "image_optimizer_default_settings.#", "1"), + testAccCheckFastlyServiceImageOptimizerDefaultSettingsAttributes(&service, &default_settings1), + ), + }, + + { + Config: testAccImageOptimizerDefaultSettingsVCLConfig(serviceName, domainName, backendAddress, backendName, block2), Check: resource.ComposeTestCheckFunc( testAccCheckServiceExists("fastly_service_vcl.foo", &service), resource.TestCheckResourceAttr("fastly_service_vcl.foo", "name", serviceName), - resource.TestCheckResourceAttr("fastly_service_vcl.foo", "backend.#", "1"), - testAccCheckFastlyServiceVCLBackendAttributes(&service, []*gofastly.Backend{&b1}), + resource.TestCheckResourceAttr("fastly_service_vcl.foo", "image_optimizer_default_settings.#", "1"), + testAccCheckFastlyServiceImageOptimizerDefaultSettingsAttributes(&service, &def_settings2), ), }, }, }) } + +func testAccCheckFastlyServiceImageOptimizerDefaultSettingsAttributes(service *gofastly.ServiceDetail, want *gofastly.ImageOptimizerDefaultSettings) resource.TestCheckFunc { + return func(_ *terraform.State) error { + conn := testAccProvider.Meta().(*APIClient).conn + have, err := conn.GetImageOptimizerDefaultSettings(&gofastly.GetImageOptimizerDefaultSettingsInput{ + ServiceID: gofastly.ToValue(service.ServiceID), + ServiceVersion: gofastly.ToValue(service.ActiveVersion.Number), + }) + if err != nil { + return fmt.Errorf("error looking up Image Optimizer default settings for (%s), version (%v): %s", gofastly.ToValue(service.Name), gofastly.ToValue(service.ActiveVersion.Number), err) + } + + if !reflect.DeepEqual(want, have) { + return fmt.Errorf("bad Image Optimizer default settings, expected (%#v), got (%#v)", want, have) + } + + return nil + } +} + +func testAccImageOptimizerDefaultSettingsVCLConfig(serviceName, domainName, backendAddress, backendName, image_optimizer_settings string) string { + return fmt.Sprintf(` + resource "fastly_service_vcl" "foo" { + name = "%s" + + domain { + name = "%s" + comment = "demo" + } + + backend { + address = "%s" + name = "%s" + port = 443 + shield = "amsterdam-nl" + } + + image_optimizer_default_settings { + %s + } + + product_enablement { + image_optimizer = true + } + + force_destroy = true + }`, serviceName, domainName, backendAddress, backendName, image_optimizer_settings) +} From dcfb3609798e0ce3bb447f0fcba11216b9fedd1b Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Wed, 15 May 2024 10:28:27 -0700 Subject: [PATCH 17/20] Update vendored go-fastly to 9.4.0. --- ...ervice_image_optimizer_default_settings.go | 40 +++++++------- go.mod | 6 ++- go.sum | 4 ++ .../fastly/go-fastly/v9/fastly/client.go | 2 +- .../fastly/go-fastly/v9/fastly/helpers.go | 2 +- .../image_optimizer_default_settings.go | 52 +++++++++---------- .../go-fastly/v9/fastly/tls_subscription.go | 16 ++++-- vendor/modules.txt | 2 +- 8 files changed, 70 insertions(+), 54 deletions(-) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index bb5002de3..bb4568b8a 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -193,18 +193,18 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context. for key, value := range modified { switch key { case "resize_filter": - var resizeFilter gofastly.ResizeFilter + var resizeFilter gofastly.ImageOptimizerResizeFilter switch value.(string) { case "lanczos3": - resizeFilter = gofastly.Lanczos3 + resizeFilter = gofastly.ImageOptimizerLanczos3 case "lanczos2": - resizeFilter = gofastly.Lanczos2 + resizeFilter = gofastly.ImageOptimizerLanczos2 case "bicubic": - resizeFilter = gofastly.Bicubic + resizeFilter = gofastly.ImageOptimizerBicubic case "bilinear": - resizeFilter = gofastly.Bilinear + resizeFilter = gofastly.ImageOptimizerBilinear case "nearest": - resizeFilter = gofastly.Nearest + resizeFilter = gofastly.ImageOptimizerNearest default: return fmt.Errorf("got unexpected resize_filter: %v", value) } @@ -214,14 +214,14 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Update(_ context. case "webp_quality": apiInput.WebpQuality = gofastly.ToPointer(value.(int)) case "jpeg_type": - var jpegType gofastly.JpegType + var jpegType gofastly.ImageOptimizerJpegType switch value.(string) { case "auto": - jpegType = gofastly.Auto + jpegType = gofastly.ImageOptimizerAuto case "baseline": - jpegType = gofastly.Baseline + jpegType = gofastly.ImageOptimizerBaseline case "progressive": - jpegType = gofastly.Progressive + jpegType = gofastly.ImageOptimizerProgressive default: return fmt.Errorf("got unexpected jpeg_type: %v", value) } @@ -266,18 +266,18 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Delete(_ context. for key, value := range resource { switch key { case "resize_filter": - var resizeFilter gofastly.ResizeFilter + var resizeFilter gofastly.ImageOptimizerResizeFilter switch value.(string) { case "lanczos3": - resizeFilter = gofastly.Lanczos3 + resizeFilter = gofastly.ImageOptimizerLanczos3 case "lanczos2": - resizeFilter = gofastly.Lanczos2 + resizeFilter = gofastly.ImageOptimizerLanczos2 case "bicubic": - resizeFilter = gofastly.Bicubic + resizeFilter = gofastly.ImageOptimizerBicubic case "bilinear": - resizeFilter = gofastly.Bilinear + resizeFilter = gofastly.ImageOptimizerBilinear case "nearest": - resizeFilter = gofastly.Nearest + resizeFilter = gofastly.ImageOptimizerNearest default: return fmt.Errorf("got unexpected resize_filter: %v", value) } @@ -287,14 +287,14 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Delete(_ context. case "webp_quality": apiInput.WebpQuality = gofastly.ToPointer(value.(int)) case "jpeg_type": - var jpegType gofastly.JpegType + var jpegType gofastly.ImageOptimizerJpegType switch value.(string) { case "auto": - jpegType = gofastly.Auto + jpegType = gofastly.ImageOptimizerAuto case "baseline": - jpegType = gofastly.Baseline + jpegType = gofastly.ImageOptimizerBaseline case "progressive": - jpegType = gofastly.Progressive + jpegType = gofastly.ImageOptimizerProgressive default: return fmt.Errorf("got unexpected jpeg_type: %v", value) } diff --git a/go.mod b/go.mod index 6bb459000..2e04cd4a2 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,12 @@ module github.com/fastly/terraform-provider-fastly -go 1.20 +go 1.21 + +toolchain go1.22.2 require ( github.com/bflad/tfproviderlint v0.29.0 - github.com/fastly/go-fastly/v9 v9.3.1 + github.com/fastly/go-fastly/v9 v9.4.0 github.com/google/go-cmp v0.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-docs v0.19.2 diff --git a/go.sum b/go.sum index 54a36709b..479a38af1 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,10 @@ github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/fastly/go-fastly/v9 v9.3.1 h1:2UZUe8Kkz60aPrkDV82dpHkEqsT/J2qxOZxFhWEJJ2k= github.com/fastly/go-fastly/v9 v9.3.1/go.mod h1:5w2jgJBZqQEebOwM/rRg7wutAcpDTziiMYWb/6qdM7U= +github.com/fastly/go-fastly/v9 v9.3.2 h1:bchK1DbVf2P/3PT19Vtkx6rB9rxKPCJJs42/0Gbga0M= +github.com/fastly/go-fastly/v9 v9.3.2/go.mod h1:5w2jgJBZqQEebOwM/rRg7wutAcpDTziiMYWb/6qdM7U= +github.com/fastly/go-fastly/v9 v9.4.0 h1:yUuj1Wy2kpK0sdB+OAxXAY54qhH8GerM7BeSngKfNRY= +github.com/fastly/go-fastly/v9 v9.4.0/go.mod h1:5w2jgJBZqQEebOwM/rRg7wutAcpDTziiMYWb/6qdM7U= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/client.go b/vendor/github.com/fastly/go-fastly/v9/fastly/client.go index 64a7df318..d14475557 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/client.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/client.go @@ -58,7 +58,7 @@ const JSONMimeType = "application/json" var ProjectURL = "github.com/fastly/go-fastly" // ProjectVersion is the version of this library. -var ProjectVersion = "9.3.1" +var ProjectVersion = "9.4.0" // UserAgent is the user agent for this particular client. var UserAgent = fmt.Sprintf("FastlyGo/%s (+%s; %s)", diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/helpers.go b/vendor/github.com/fastly/go-fastly/v9/fastly/helpers.go index 966cf4c28..3b5bb684c 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/helpers.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/helpers.go @@ -2,7 +2,7 @@ package fastly // MultiConstraint is a generic constraint for ToPointer/ToValue. type MultiConstraint interface { - ~string | ~int | int32 | ~int64 | uint | uint8 | uint32 | uint64 | float64 | ~bool + []string | ~string | ~int | int32 | ~int64 | uint | uint8 | uint32 | uint64 | float64 | ~bool } // ToPointer converts T to *T. diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go index 6a7ed7d21..0e352547c 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/image_optimizer_default_settings.go @@ -5,68 +5,68 @@ import ( "fmt" ) -// ResizeFilter is a base for the different ResizeFilter variants. -type ResizeFilter int64 +// ImageOptimizerResizeFilter is a base for the different ImageOptimizerResizeFilter variants. +type ImageOptimizerResizeFilter int64 -func (r ResizeFilter) String() string { +func (r ImageOptimizerResizeFilter) String() string { switch r { - case Lanczos3: + case ImageOptimizerLanczos3: return "lanczos3" - case Lanczos2: + case ImageOptimizerLanczos2: return "lanczos2" - case Bicubic: + case ImageOptimizerBicubic: return "bicubic" - case Bilinear: + case ImageOptimizerBilinear: return "bilinear" - case Nearest: + case ImageOptimizerNearest: return "nearest" } return "lanczos3" // default } -func (r ResizeFilter) MarshalJSON() ([]byte, error) { +func (r ImageOptimizerResizeFilter) MarshalJSON() ([]byte, error) { return json.Marshal(r.String()) } const ( // A Lanczos filter with a kernel size of 3. Lanczos filters can detect edges and linear features within an image, providing the best possible reconstruction. - Lanczos3 ResizeFilter = iota + ImageOptimizerLanczos3 ImageOptimizerResizeFilter = iota // A Lanczos filter with a kernel size of 2. - Lanczos2 + ImageOptimizerLanczos2 // A filter using an average of a 4x4 environment of pixels, weighing the innermost pixels higher. - Bicubic + ImageOptimizerBicubic // A filter using an average of a 2x2 environment of pixels. - Bilinear + ImageOptimizerBilinear // A filter using the value of nearby translated pixel values. Preserves hard edges. - Nearest + ImageOptimizerNearest ) -// JpegType is a base for different JpegType variants -type JpegType int64 +// ImageOptimizerJpegType is a base for different ImageOptimizerJpegType variants +type ImageOptimizerJpegType int64 -func (r JpegType) String() string { +func (r ImageOptimizerJpegType) String() string { switch r { - case Auto: + case ImageOptimizerAuto: return "auto" - case Baseline: + case ImageOptimizerBaseline: return "baseline" - case Progressive: + case ImageOptimizerProgressive: return "progressive" } return "auto" // default } -func (r JpegType) MarshalJSON() ([]byte, error) { +func (r ImageOptimizerJpegType) MarshalJSON() ([]byte, error) { return json.Marshal(r.String()) } const ( // Match the input JPEG type, or baseline if transforming from a non-JPEG input. - Auto JpegType = iota + ImageOptimizerAuto ImageOptimizerJpegType = iota // Output baseline JPEG images - Baseline + ImageOptimizerBaseline // Output progressive JPEG images - Progressive + ImageOptimizerProgressive ) // ImageOptimizerDefaultSettings represents the returned Image Optimizer default settings for a given service. @@ -106,13 +106,13 @@ type UpdateImageOptimizerDefaultSettingsInput struct { // ServiceVersion is the specific configuration version (required). ServiceVersion int `json:"-"` // The type of filter to use while resizing an image. - ResizeFilter *ResizeFilter `json:"resize_filter,omitempty"` + ResizeFilter *ImageOptimizerResizeFilter `json:"resize_filter,omitempty"` // Controls whether or not to default to WebP output when the client supports it. This is equivalent to adding "auto=webp" to all image optimizer requests. Webp *bool `json:"webp,omitempty"` // The default quality to use with WebP output. This can be overridden with the second option in the "quality" URL parameter on specific image optimizer requests. WebpQuality *int `json:"webp_quality,omitempty"` // The default type of JPEG output to use. This can be overridden with "format=bjpeg" and "format=pjpeg" on specific image optimizer requests. - JpegType *JpegType `json:"jpeg_type,omitempty"` + JpegType *ImageOptimizerJpegType `json:"jpeg_type,omitempty"` // The default quality to use with JPEG output. This can be overridden with the "quality" parameter on specific image optimizer requests. JpegQuality *int `json:"jpeg_quality,omitempty"` // Whether or not we should allow output images to render at sizes larger than input. diff --git a/vendor/github.com/fastly/go-fastly/v9/fastly/tls_subscription.go b/vendor/github.com/fastly/go-fastly/v9/fastly/tls_subscription.go index 7cbb28f39..deecb2c42 100644 --- a/vendor/github.com/fastly/go-fastly/v9/fastly/tls_subscription.go +++ b/vendor/github.com/fastly/go-fastly/v9/fastly/tls_subscription.go @@ -25,7 +25,17 @@ type TLSSubscription struct { // TLSSubscriptionCertificate represents a subscription certificate. type TLSSubscriptionCertificate struct { - ID string `jsonapi:"primary,tls_certificate"` + ID string `jsonapi:"primary,tls_certificate"` + CreatedAt *time.Time `jsonapi:"attr,created_at,iso8601"` + IssuedTo string `jsonapi:"attr,issued_to"` + Issuer string `jsonapi:"attr,issuer"` + Name string `jsonapi:"attr,name"` + NotAfter *time.Time `jsonapi:"attr,not_after,iso8601"` + NotBefore *time.Time `jsonapi:"attr,not_before,iso8601"` + Replace bool `jsonapi:"attr,replace"` + SerialNumber string `jsonapi:"attr,serial_number"` + SignatureAlgorithm string `jsonapi:"attr,signature_algorithm"` + UpdatedAt *time.Time `jsonapi:"attr,updated_at,iso8601"` } // TLSAuthorizations gives information needed to verify domain ownership in @@ -66,7 +76,7 @@ type ListTLSSubscriptionsInput struct { FilterState string // Limit the returned subscriptions to those that include the specific domain. FilterTLSDomainsID string - // Include related objects. Optional, comma-separated values. Permitted values: tls_authorizations. + // Include related objects. Optional, comma-separated values. Permitted values: tls_authorizations, tls_authorizations.globalsign_email_challenge, tls_authorizations.self_managed_http_challenge, and tls_certificates. Include string // Current page. PageNumber int @@ -201,7 +211,7 @@ func domainInSlice(haystack []*TLSDomain, needle *TLSDomain) bool { type GetTLSSubscriptionInput struct { // ID of the TLS subscription to fetch. ID string - // Include related objects. Optional, comma-separated values. Permitted values: tls_authorizations. + // Include related objects. Optional, comma-separated values. Permitted values: tls_authorizations, tls_authorizations.globalsign_email_challenge, tls_authorizations.self_managed_http_challenge, and tls_certificates. Include *string } diff --git a/vendor/modules.txt b/vendor/modules.txt index c06e35eaa..927647393 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -225,7 +225,7 @@ github.com/cloudflare/circl/sign/ed448 # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/fastly/go-fastly/v9 v9.3.1 +# github.com/fastly/go-fastly/v9 v9.4.0 ## explicit; go 1.20 github.com/fastly/go-fastly/v9/fastly # github.com/fatih/color v1.16.0 From e4cebed03701c5d311248cdb6047ff73cdea9312 Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Wed, 15 May 2024 15:39:16 -0700 Subject: [PATCH 18/20] Add debug message for ignoring image-optimizer-disabled error on deletion. This is working well! Just wanted to add this to double-confirm it's doing what I expect. --- fastly/block_fastly_service_image_optimizer_default_settings.go | 1 + 1 file changed, 1 insertion(+) diff --git a/fastly/block_fastly_service_image_optimizer_default_settings.go b/fastly/block_fastly_service_image_optimizer_default_settings.go index bb4568b8a..246712411 100644 --- a/fastly/block_fastly_service_image_optimizer_default_settings.go +++ b/fastly/block_fastly_service_image_optimizer_default_settings.go @@ -322,6 +322,7 @@ func (h *ImageOptimizerDefaultSettingsServiceAttributeHandler) Delete(_ context. if he.StatusCode == http.StatusBadRequest { for _, e := range he.Errors { if strings.Contains(e.Detail, "Image Optimizer is not enabled on this service") { + log.Printf("[DEBUG] Ignoring error %v, as a service without Image Optimizer enabled already effectively has no default settings.", e.Detail) return nil } } From 2bcda5f5919670a0ad959fafe0fe750dc5c5148c Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Wed, 15 May 2024 15:41:03 -0700 Subject: [PATCH 19/20] Remove toolchain directive. --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 2e04cd4a2..5e05232ab 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/fastly/terraform-provider-fastly go 1.21 -toolchain go1.22.2 - require ( github.com/bflad/tfproviderlint v0.29.0 github.com/fastly/go-fastly/v9 v9.4.0 From 7ffa4f62785005e3fa084ae933cb6dd844efff3e Mon Sep 17 00:00:00 2001 From: Dabo Ross Date: Wed, 15 May 2024 16:53:33 -0700 Subject: [PATCH 20/20] Undo go version bump. Not sure why updating had caused this, but this should still work. --- go.mod | 2 +- go.sum | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 5e05232ab..22505edf5 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/fastly/terraform-provider-fastly -go 1.21 +go 1.20 require ( github.com/bflad/tfproviderlint v0.29.0 diff --git a/go.sum b/go.sum index 479a38af1..27f451099 100644 --- a/go.sum +++ b/go.sum @@ -36,10 +36,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/fastly/go-fastly/v9 v9.3.1 h1:2UZUe8Kkz60aPrkDV82dpHkEqsT/J2qxOZxFhWEJJ2k= -github.com/fastly/go-fastly/v9 v9.3.1/go.mod h1:5w2jgJBZqQEebOwM/rRg7wutAcpDTziiMYWb/6qdM7U= -github.com/fastly/go-fastly/v9 v9.3.2 h1:bchK1DbVf2P/3PT19Vtkx6rB9rxKPCJJs42/0Gbga0M= -github.com/fastly/go-fastly/v9 v9.3.2/go.mod h1:5w2jgJBZqQEebOwM/rRg7wutAcpDTziiMYWb/6qdM7U= github.com/fastly/go-fastly/v9 v9.4.0 h1:yUuj1Wy2kpK0sdB+OAxXAY54qhH8GerM7BeSngKfNRY= github.com/fastly/go-fastly/v9 v9.4.0/go.mod h1:5w2jgJBZqQEebOwM/rRg7wutAcpDTziiMYWb/6qdM7U= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=