From 94c1f447b37e4b18f1f308f57090505e596041b2 Mon Sep 17 00:00:00 2001
From: "Kevin P. Fleming" <kpfleming@users.noreply.github.com>
Date: Mon, 11 Nov 2024 12:48:08 -0500
Subject: [PATCH] feat(product_enablement): Add support for Log Explorer &
 Insights product. (#896)

The 'product_enablement' block in both Delivery (VCL) and Compute
(WASM) services can now be used to enable/disable the Log Explorer &
Insights product.
---
 docs/resources/service_compute.md             |  1 +
 docs/resources/service_vcl.md                 |  1 +
 ...block_fastly_service_product_enablement.go | 62 ++++++++++++++++++-
 ..._fastly_service_product_enablement_test.go | 13 ++--
 4 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/docs/resources/service_compute.md b/docs/resources/service_compute.md
index 7c3ad0daf..0b6317f3a 100644
--- a/docs/resources/service_compute.md
+++ b/docs/resources/service_compute.md
@@ -699,6 +699,7 @@ Optional:
 Optional:
 
 - `fanout` (Boolean) Enable Fanout support
+- `log_explorer_insights` (Boolean) Enable Log Explorer & Insights
 - `name` (String) Used by the provider to identify modified settings (changing this value will force the entire block to be deleted, then recreated)
 - `websockets` (Boolean) Enable WebSockets support
 
diff --git a/docs/resources/service_vcl.md b/docs/resources/service_vcl.md
index 31276bf01..93477c015 100644
--- a/docs/resources/service_vcl.md
+++ b/docs/resources/service_vcl.md
@@ -1158,6 +1158,7 @@ Optional:
 - `brotli_compression` (Boolean) Enable Brotli Compression support
 - `domain_inspector` (Boolean) Enable Domain Inspector support
 - `image_optimizer` (Boolean) Enable Image Optimizer support (all backends must have a `shield` attribute)
+- `log_explorer_insights` (Boolean) Enable Log Explorer & Insights
 - `name` (String) Used by the provider to identify modified settings (changing this value will force the entire block to be deleted, then recreated)
 - `origin_inspector` (Boolean) Enable Origin Inspector support
 - `websockets` (Boolean) Enable WebSockets support
diff --git a/fastly/block_fastly_service_product_enablement.go b/fastly/block_fastly_service_product_enablement.go
index 9f8c4835f..da6c5e86d 100644
--- a/fastly/block_fastly_service_product_enablement.go
+++ b/fastly/block_fastly_service_product_enablement.go
@@ -42,6 +42,7 @@ func (h *ProductEnablementServiceAttributeHandler) GetSchema() *schema.Schema {
 		},
 	}
 
+	// These products are supported only on Compute (WASM) services.
 	if h.GetServiceMetadata().serviceType == ServiceTypeCompute {
 		blockAttributes["fanout"] = &schema.Schema{
 			Type:        schema.TypeBool,
@@ -50,6 +51,7 @@ func (h *ProductEnablementServiceAttributeHandler) GetSchema() *schema.Schema {
 		}
 	}
 
+	// These products are supported only on Delivery (VCL) services.
 	if h.GetServiceMetadata().serviceType == ServiceTypeVCL {
 		blockAttributes["bot_management"] = &schema.Schema{
 			Type:        schema.TypeBool,
@@ -78,12 +80,17 @@ func (h *ProductEnablementServiceAttributeHandler) GetSchema() *schema.Schema {
 		}
 	}
 
-	// websockets is supported for both Compute (wasm) and Deliver (vcl) services.
+	// These products are supported for both Compute (WASM) and Delivery (VCL) services.
 	blockAttributes["websockets"] = &schema.Schema{
 		Type:        schema.TypeBool,
 		Optional:    true,
 		Description: "Enable WebSockets support",
 	}
+	blockAttributes["log_explorer_insights"] = &schema.Schema{
+		Type:        schema.TypeBool,
+		Optional:    true,
+		Description: "Enable Log Explorer & Insights",
+	}
 
 	// NOTE: Min/MaxItems: 1 (to enforce only one product_enablement per service).
 	// lintignore:S018
@@ -182,6 +189,17 @@ func (h *ProductEnablementServiceAttributeHandler) Create(_ context.Context, d *
 		}
 	}
 
+	if resource["log_explorer_insights"].(bool) {
+		log.Println("[DEBUG] log_explorer_insights set")
+		_, err := conn.EnableProduct(&gofastly.ProductEnablementInput{
+			ProductID: gofastly.ProductLogExplorerInsights,
+			ServiceID: serviceID,
+		})
+		if err != nil {
+			return fmt.Errorf("failed to enable log_explorer_insights: %w", err)
+		}
+	}
+
 	return nil
 }
 
@@ -266,6 +284,13 @@ func (h *ProductEnablementServiceAttributeHandler) Read(_ context.Context, d *sc
 			result["websockets"] = true
 		}
 
+		if _, err := conn.GetProduct(&gofastly.ProductEnablementInput{
+			ProductID: gofastly.ProductLogExplorerInsights,
+			ServiceID: d.Id(),
+		}); err == nil {
+			result["log_explorer_insights"] = true
+		}
+
 		results := []map[string]any{result}
 
 		// IMPORTANT: Avoid runtime panic "set item just set doesn't exist".
@@ -464,6 +489,30 @@ func (h *ProductEnablementServiceAttributeHandler) Update(_ context.Context, d *
 		}
 	}
 
+	if v, ok := modified["log_explorer_insights"]; ok {
+		if v.(bool) {
+			log.Println("[DEBUG] log_explorer_insights will be enabled")
+			_, err := conn.EnableProduct(&gofastly.ProductEnablementInput{
+				ProductID: gofastly.ProductLogExplorerInsights,
+				ServiceID: serviceID,
+			})
+			if err != nil {
+				return fmt.Errorf("failed to enable log_explorer_insights: %w", err)
+			}
+		} else {
+			log.Println("[DEBUG] log_explorer_insights will be disabled")
+			err := conn.DisableProduct(&gofastly.ProductEnablementInput{
+				ProductID: gofastly.ProductLogExplorerInsights,
+				ServiceID: serviceID,
+			})
+			if err != nil {
+				if e := h.checkAPIError(err); e != nil {
+					return e
+				}
+			}
+		}
+	}
+
 	return nil
 }
 
@@ -580,6 +629,17 @@ func (h *ProductEnablementServiceAttributeHandler) Delete(_ context.Context, d *
 		}
 	}
 
+	log.Println("[DEBUG] disable log_explorer_insights")
+	err = conn.DisableProduct(&gofastly.ProductEnablementInput{
+		ProductID: gofastly.ProductLogExplorerInsights,
+		ServiceID: d.Id(),
+	})
+	if err != nil {
+		if e := h.checkAPIError(err); e != nil {
+			return e
+		}
+	}
+
 	return nil
 }
 
diff --git a/fastly/block_fastly_service_product_enablement_test.go b/fastly/block_fastly_service_product_enablement_test.go
index b4158e47c..20c1fde20 100644
--- a/fastly/block_fastly_service_product_enablement_test.go
+++ b/fastly/block_fastly_service_product_enablement_test.go
@@ -33,12 +33,13 @@ func TestAccFastlyServiceVCLProductEnablement_basic(t *testing.T) {
     }
 
     product_enablement {
-      bot_management     = false
-      brotli_compression = true
-      domain_inspector   = false
-      image_optimizer    = false
-      origin_inspector   = false
-      websockets         = false
+      bot_management        = false
+      brotli_compression    = true
+      domain_inspector      = false
+      image_optimizer       = false
+      log_explorer_insights = false
+      origin_inspector      = false
+      websockets            = false
     }
 
     force_destroy = true