From d7f329fcffc3963741efb58ae2fb9cdc9bf5a4a3 Mon Sep 17 00:00:00 2001 From: Nawaz Dhandala Date: Mon, 19 Jan 2026 17:21:10 +0000 Subject: [PATCH] feat: add comprehensive CRUD tests for probe, label, monitor status, and incident severity resources --- .gitignore | 8 + E2E/Terraform/e2e-tests/scripts/index.sh | 7 +- .../e2e-tests/scripts/run-crud-tests.sh | 323 ++++++++++++++++++ E2E/Terraform/e2e-tests/scripts/run-tests.sh | 1 + .../e2e-tests/tests/08-probe/main.tf | 30 ++ .../e2e-tests/tests/08-probe/variables.tf | 15 + .../e2e-tests/tests/09-label-crud/main.tf | 38 +++ .../tests/09-label-crud/variables.tf | 33 ++ .../tests/10-monitor-status-crud/main.tf | 42 +++ .../tests/10-monitor-status-crud/variables.tf | 39 +++ .../tests/11-incident-severity-crud/main.tf | 42 +++ .../11-incident-severity-crud/variables.tf | 39 +++ .../Core/ResourceGenerator.ts | 13 +- 13 files changed, 627 insertions(+), 3 deletions(-) create mode 100755 E2E/Terraform/e2e-tests/scripts/run-crud-tests.sh create mode 100644 E2E/Terraform/e2e-tests/tests/08-probe/main.tf create mode 100644 E2E/Terraform/e2e-tests/tests/08-probe/variables.tf create mode 100644 E2E/Terraform/e2e-tests/tests/09-label-crud/main.tf create mode 100644 E2E/Terraform/e2e-tests/tests/09-label-crud/variables.tf create mode 100644 E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/main.tf create mode 100644 E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/variables.tf create mode 100644 E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/main.tf create mode 100644 E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/variables.tf diff --git a/.gitignore b/.gitignore index e328206f65..72999810c3 100644 --- a/.gitignore +++ b/.gitignore @@ -130,3 +130,11 @@ Dashboard/public/sw.js .claude/settings.local.json Common/.claude/settings.local.json E2E/Terraform/e2e-tests/test-env.sh + +# Terraform state and plan files +*.tfplan +tfplan +terraform.tfstate +terraform.tfstate.backup +.terraform/ +.terraform.lock.hcl diff --git a/E2E/Terraform/e2e-tests/scripts/index.sh b/E2E/Terraform/e2e-tests/scripts/index.sh index e5ffaa77eb..a6a9f90d4b 100755 --- a/E2E/Terraform/e2e-tests/scripts/index.sh +++ b/E2E/Terraform/e2e-tests/scripts/index.sh @@ -41,11 +41,16 @@ echo "=== Step 6: Setting up test account ===" cd "$TEST_DIR" "$SCRIPT_DIR/setup-test-account.sh" -# Step 7: Run tests +# Step 7: Run basic tests echo "" echo "=== Step 7: Running Terraform E2E Tests ===" "$SCRIPT_DIR/run-tests.sh" +# Step 8: Run CRUD tests (create, update, API validation, destroy) +echo "" +echo "=== Step 8: Running Terraform CRUD Tests ===" +"$SCRIPT_DIR/run-crud-tests.sh" + echo "" echo "==========================================" echo "E2E Tests Completed Successfully!" diff --git a/E2E/Terraform/e2e-tests/scripts/run-crud-tests.sh b/E2E/Terraform/e2e-tests/scripts/run-crud-tests.sh new file mode 100755 index 0000000000..5898f186c9 --- /dev/null +++ b/E2E/Terraform/e2e-tests/scripts/run-crud-tests.sh @@ -0,0 +1,323 @@ +#!/bin/bash +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TEST_DIR="$(dirname "$SCRIPT_DIR")" +PROVIDER_DIR="$TEST_DIR/../../../Terraform/terraform-provider-oneuptime" + +# Load test environment +source "$TEST_DIR/test-env.sh" + +echo "=== Running Terraform CRUD E2E Tests ===" +echo "OneUptime URL: $ONEUPTIME_URL" +echo "Project ID: $ONEUPTIME_PROJECT_ID" + +# Build and install provider locally +echo "" +echo "=== Building Terraform Provider ===" +cd "$PROVIDER_DIR" +go mod tidy +go build -o terraform-provider-oneuptime + +# Install provider +OS=$(go env GOOS) +ARCH=$(go env GOARCH) +INSTALL_DIR="$HOME/.terraform.d/plugins/registry.terraform.io/oneuptime/oneuptime/1.0.0/${OS}_${ARCH}" +mkdir -p "$INSTALL_DIR" +cp terraform-provider-oneuptime "$INSTALL_DIR/" + +echo "Provider installed to: $INSTALL_DIR" + +# Helper function to validate resource via API +validate_api() { + local endpoint="$1" + local resource_id="$2" + local expected_field="$3" + local expected_value="$4" + + echo " Validating via API: GET $endpoint/$resource_id" + + local response=$(curl -sf -X POST "${ONEUPTIME_URL}/api${endpoint}/${resource_id}/get-item" \ + -H "Content-Type: application/json" \ + -H "Apikey: $TF_VAR_api_key" \ + -H "projectid: $TF_VAR_project_id" \ + -d "{\"select\": {\"${expected_field}\": true}}" 2>&1) + + if [ $? -ne 0 ]; then + echo " API validation FAILED: Could not fetch resource" + return 1 + fi + + # Extract the value - handle both direct string and wrapper object formats + local actual_value=$(echo "$response" | jq -r ".data.${expected_field} // .${expected_field}" 2>/dev/null) + + # Handle wrapper object format (e.g., {"_type":"...", "value":"..."}) + if echo "$actual_value" | jq -e '.value' > /dev/null 2>&1; then + actual_value=$(echo "$actual_value" | jq -r '.value') + fi + + if [ "$actual_value" = "$expected_value" ]; then + echo " API validation PASSED: $expected_field = '$expected_value'" + return 0 + else + echo " API validation FAILED: Expected $expected_field='$expected_value', got '$actual_value'" + return 1 + fi +} + +PASSED=() +FAILED=() + +####################################### +# Test 1: Label CRUD +####################################### +echo "" +echo "==========================================" +echo "CRUD Test: Label" +echo "==========================================" + +test_path="$TEST_DIR/tests/09-label-crud" +cd "$test_path" +rm -f tfplan terraform.tfstate terraform.tfstate.backup + +# Step 1: Create +echo " [1/6] Creating label..." +if ! terraform plan -out=tfplan \ + -var="label_name=terraform-crud-label" \ + -var="label_description=Initial description" \ + -var="label_color=#FF0000" 2>&1; then + echo " FAILED: Plan failed" + FAILED+=("09-label-crud (create plan)") +else + if ! terraform apply -auto-approve tfplan 2>&1; then + echo " FAILED: Apply failed" + FAILED+=("09-label-crud (create apply)") + else + LABEL_ID=$(terraform output -raw label_id) + echo " Created label ID: $LABEL_ID" + + # Step 2: Validate via API after create + echo " [2/6] Validating creation via API..." + if validate_api "/label" "$LABEL_ID" "name" "terraform-crud-label"; then + + # Step 3: Update + echo " [3/6] Updating label..." + if ! terraform plan -out=tfplan \ + -var="label_name=terraform-crud-label-updated" \ + -var="label_description=Updated description" \ + -var="label_color=#00FF00" 2>&1; then + echo " FAILED: Update plan failed" + FAILED+=("09-label-crud (update plan)") + else + if ! terraform apply -auto-approve tfplan 2>&1; then + echo " FAILED: Update apply failed" + FAILED+=("09-label-crud (update apply)") + else + echo " Label updated successfully" + + # Step 4: Validate via API after update + echo " [4/6] Validating update via API..." + if validate_api "/label" "$LABEL_ID" "name" "terraform-crud-label-updated"; then + + # Step 5: Verify color was updated + echo " [5/6] Validating color update via API..." + if validate_api "/label" "$LABEL_ID" "color" "#00FF00"; then + PASSED+=("09-label-crud") + else + FAILED+=("09-label-crud (color validation)") + fi + else + FAILED+=("09-label-crud (update validation)") + fi + fi + fi + else + FAILED+=("09-label-crud (create validation)") + fi + + # Step 6: Destroy + echo " [6/6] Destroying label..." + terraform destroy -auto-approve \ + -var="label_name=terraform-crud-label-updated" \ + -var="label_description=Updated description" \ + -var="label_color=#00FF00" 2>&1 || true + fi +fi +rm -f tfplan terraform.tfstate terraform.tfstate.backup + +####################################### +# Test 2: Monitor Status CRUD +####################################### +echo "" +echo "==========================================" +echo "CRUD Test: Monitor Status" +echo "==========================================" + +test_path="$TEST_DIR/tests/10-monitor-status-crud" +cd "$test_path" +rm -f tfplan terraform.tfstate terraform.tfstate.backup + +# Step 1: Create +echo " [1/6] Creating monitor status..." +if ! terraform plan -out=tfplan \ + -var="status_name=terraform-crud-status" \ + -var="status_description=Initial status description" \ + -var="status_color=#00FF00" \ + -var="status_priority=100" 2>&1; then + echo " FAILED: Plan failed" + FAILED+=("10-monitor-status-crud (create plan)") +else + if ! terraform apply -auto-approve tfplan 2>&1; then + echo " FAILED: Apply failed" + FAILED+=("10-monitor-status-crud (create apply)") + else + STATUS_ID=$(terraform output -raw monitor_status_id) + echo " Created monitor status ID: $STATUS_ID" + + # Step 2: Validate via API after create + echo " [2/6] Validating creation via API..." + if validate_api "/monitor-status" "$STATUS_ID" "name" "terraform-crud-status"; then + + # Step 3: Update (note: priority cannot be updated per API restriction) + echo " [3/6] Updating monitor status..." + if ! terraform plan -out=tfplan \ + -var="status_name=terraform-crud-status-updated" \ + -var="status_description=Updated status description" \ + -var="status_color=#0000FF" \ + -var="status_priority=100" 2>&1; then + echo " FAILED: Update plan failed" + FAILED+=("10-monitor-status-crud (update plan)") + else + if ! terraform apply -auto-approve tfplan 2>&1; then + echo " FAILED: Update apply failed" + FAILED+=("10-monitor-status-crud (update apply)") + else + echo " Monitor status updated successfully" + + # Step 4: Validate via API after update + echo " [4/6] Validating update via API..." + if validate_api "/monitor-status" "$STATUS_ID" "name" "terraform-crud-status-updated"; then + + # Step 5: Verify color was updated + echo " [5/6] Validating color update via API..." + if validate_api "/monitor-status" "$STATUS_ID" "color" "#0000FF"; then + PASSED+=("10-monitor-status-crud") + else + FAILED+=("10-monitor-status-crud (color validation)") + fi + else + FAILED+=("10-monitor-status-crud (update validation)") + fi + fi + fi + else + FAILED+=("10-monitor-status-crud (create validation)") + fi + + # Step 6: Destroy + echo " [6/6] Destroying monitor status..." + terraform destroy -auto-approve \ + -var="status_name=terraform-crud-status-updated" \ + -var="status_description=Updated status description" \ + -var="status_color=#0000FF" \ + -var="status_priority=100" 2>&1 || true + fi +fi +rm -f tfplan terraform.tfstate terraform.tfstate.backup + +####################################### +# Test 3: Incident Severity CRUD +####################################### +echo "" +echo "==========================================" +echo "CRUD Test: Incident Severity" +echo "==========================================" + +test_path="$TEST_DIR/tests/11-incident-severity-crud" +cd "$test_path" +rm -f tfplan terraform.tfstate terraform.tfstate.backup + +# Step 1: Create +echo " [1/6] Creating incident severity..." +if ! terraform plan -out=tfplan \ + -var="severity_name=terraform-crud-severity" \ + -var="severity_description=Initial severity description" \ + -var="severity_color=#FFA500" \ + -var="severity_order=100" 2>&1; then + echo " FAILED: Plan failed" + FAILED+=("11-incident-severity-crud (create plan)") +else + if ! terraform apply -auto-approve tfplan 2>&1; then + echo " FAILED: Apply failed" + FAILED+=("11-incident-severity-crud (create apply)") + else + SEVERITY_ID=$(terraform output -raw incident_severity_id) + echo " Created incident severity ID: $SEVERITY_ID" + + # Step 2: Validate via API after create + echo " [2/6] Validating creation via API..." + if validate_api "/incident-severity" "$SEVERITY_ID" "name" "terraform-crud-severity"; then + + # Step 3: Update (note: order cannot be updated per API restriction) + echo " [3/6] Updating incident severity..." + if ! terraform plan -out=tfplan \ + -var="severity_name=terraform-crud-severity-updated" \ + -var="severity_description=Updated severity description" \ + -var="severity_color=#FF00FF" \ + -var="severity_order=100" 2>&1; then + echo " FAILED: Update plan failed" + FAILED+=("11-incident-severity-crud (update plan)") + else + if ! terraform apply -auto-approve tfplan 2>&1; then + echo " FAILED: Update apply failed" + FAILED+=("11-incident-severity-crud (update apply)") + else + echo " Incident severity updated successfully" + + # Step 4: Validate via API after update + echo " [4/6] Validating update via API..." + if validate_api "/incident-severity" "$SEVERITY_ID" "name" "terraform-crud-severity-updated"; then + + # Step 5: Verify color was updated + echo " [5/6] Validating color update via API..." + if validate_api "/incident-severity" "$SEVERITY_ID" "color" "#FF00FF"; then + PASSED+=("11-incident-severity-crud") + else + FAILED+=("11-incident-severity-crud (color validation)") + fi + else + FAILED+=("11-incident-severity-crud (update validation)") + fi + fi + fi + else + FAILED+=("11-incident-severity-crud (create validation)") + fi + + # Step 6: Destroy + echo " [6/6] Destroying incident severity..." + terraform destroy -auto-approve \ + -var="severity_name=terraform-crud-severity-updated" \ + -var="severity_description=Updated severity description" \ + -var="severity_color=#FF00FF" \ + -var="severity_order=100" 2>&1 || true + fi +fi +rm -f tfplan terraform.tfstate terraform.tfstate.backup + +# Summary +echo "" +echo "==========================================" +echo "CRUD Test Summary" +echo "==========================================" +echo "Passed: ${#PASSED[@]}" +for t in "${PASSED[@]}"; do echo " - $t"; done + +if [ ${#FAILED[@]} -gt 0 ]; then + echo "Failed: ${#FAILED[@]}" + for t in "${FAILED[@]}"; do echo " - $t"; done + exit 1 +fi + +echo "" +echo "All CRUD tests passed!" diff --git a/E2E/Terraform/e2e-tests/scripts/run-tests.sh b/E2E/Terraform/e2e-tests/scripts/run-tests.sh index cb10029c86..884b595977 100755 --- a/E2E/Terraform/e2e-tests/scripts/run-tests.sh +++ b/E2E/Terraform/e2e-tests/scripts/run-tests.sh @@ -47,6 +47,7 @@ TEST_DIRS=( "05-status-page" "06-alert-severity" "07-alert-state" + "08-probe" ) PASSED=() diff --git a/E2E/Terraform/e2e-tests/tests/08-probe/main.tf b/E2E/Terraform/e2e-tests/tests/08-probe/main.tf new file mode 100644 index 0000000000..23aeab27e8 --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/08-probe/main.tf @@ -0,0 +1,30 @@ +terraform { + required_providers { + oneuptime = { + source = "oneuptime/oneuptime" + version = "1.0.0" + } + } +} + +provider "oneuptime" { + oneuptime_url = var.oneuptime_url + api_key = var.api_key +} + +# Test for GitHub Issue #2228: probe_version field produces inconsistent result after apply +# The probe_version should remain as "1.0.0" and not be converted to JSON like {"_type":"Version","value":"1.0.0"} +resource "oneuptime_probe" "test" { + project_id = var.project_id + key = "terraform-e2e-probe-key-${formatdate("YYYYMMDDhhmmss", timestamp())}" + name = "terraform-e2e-probe-${formatdate("YYYYMMDDhhmmss", timestamp())}" + probe_version = "1.0.0" +} + +output "probe_id" { + value = oneuptime_probe.test.id +} + +output "probe_version" { + value = oneuptime_probe.test.probe_version +} diff --git a/E2E/Terraform/e2e-tests/tests/08-probe/variables.tf b/E2E/Terraform/e2e-tests/tests/08-probe/variables.tf new file mode 100644 index 0000000000..3817cd77a2 --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/08-probe/variables.tf @@ -0,0 +1,15 @@ +variable "oneuptime_url" { + type = string + description = "OneUptime API URL" +} + +variable "api_key" { + type = string + description = "OneUptime API Key" + sensitive = true +} + +variable "project_id" { + type = string + description = "OneUptime Project ID" +} diff --git a/E2E/Terraform/e2e-tests/tests/09-label-crud/main.tf b/E2E/Terraform/e2e-tests/tests/09-label-crud/main.tf new file mode 100644 index 0000000000..51c1ffd561 --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/09-label-crud/main.tf @@ -0,0 +1,38 @@ +terraform { + required_providers { + oneuptime = { + source = "oneuptime/oneuptime" + version = "1.0.0" + } + } +} + +provider "oneuptime" { + oneuptime_url = var.oneuptime_url + api_key = var.api_key +} + +# Comprehensive CRUD test for label resource +# This test creates a label, then updates can be applied via variable changes +resource "oneuptime_label" "test" { + project_id = var.project_id + name = var.label_name + description = var.label_description + color = var.label_color +} + +output "label_id" { + value = oneuptime_label.test.id +} + +output "label_name" { + value = oneuptime_label.test.name +} + +output "label_description" { + value = oneuptime_label.test.description +} + +output "label_color" { + value = oneuptime_label.test.color +} diff --git a/E2E/Terraform/e2e-tests/tests/09-label-crud/variables.tf b/E2E/Terraform/e2e-tests/tests/09-label-crud/variables.tf new file mode 100644 index 0000000000..6330c85e4e --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/09-label-crud/variables.tf @@ -0,0 +1,33 @@ +variable "oneuptime_url" { + type = string + description = "OneUptime API URL" +} + +variable "api_key" { + type = string + description = "OneUptime API Key" + sensitive = true +} + +variable "project_id" { + type = string + description = "OneUptime Project ID" +} + +variable "label_name" { + type = string + description = "Label name" + default = "terraform-crud-test-label" +} + +variable "label_description" { + type = string + description = "Label description" + default = "Initial description for CRUD test" +} + +variable "label_color" { + type = string + description = "Label color" + default = "#FF0000" +} diff --git a/E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/main.tf b/E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/main.tf new file mode 100644 index 0000000000..15ba403f48 --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/main.tf @@ -0,0 +1,42 @@ +terraform { + required_providers { + oneuptime = { + source = "oneuptime/oneuptime" + version = "1.0.0" + } + } +} + +provider "oneuptime" { + oneuptime_url = var.oneuptime_url + api_key = var.api_key +} + +# Comprehensive CRUD test for monitor_status resource +resource "oneuptime_monitor_status" "test" { + project_id = var.project_id + name = var.status_name + description = var.status_description + color = var.status_color + priority = var.status_priority +} + +output "monitor_status_id" { + value = oneuptime_monitor_status.test.id +} + +output "monitor_status_name" { + value = oneuptime_monitor_status.test.name +} + +output "monitor_status_description" { + value = oneuptime_monitor_status.test.description +} + +output "monitor_status_color" { + value = oneuptime_monitor_status.test.color +} + +output "monitor_status_priority" { + value = oneuptime_monitor_status.test.priority +} diff --git a/E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/variables.tf b/E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/variables.tf new file mode 100644 index 0000000000..d7b8758134 --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/10-monitor-status-crud/variables.tf @@ -0,0 +1,39 @@ +variable "oneuptime_url" { + type = string + description = "OneUptime API URL" +} + +variable "api_key" { + type = string + description = "OneUptime API Key" + sensitive = true +} + +variable "project_id" { + type = string + description = "OneUptime Project ID" +} + +variable "status_name" { + type = string + description = "Monitor status name" + default = "terraform-crud-test-status" +} + +variable "status_description" { + type = string + description = "Monitor status description" + default = "Initial description for CRUD test" +} + +variable "status_color" { + type = string + description = "Monitor status color" + default = "#00FF00" +} + +variable "status_priority" { + type = number + description = "Monitor status priority" + default = 100 +} diff --git a/E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/main.tf b/E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/main.tf new file mode 100644 index 0000000000..478365b43c --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/main.tf @@ -0,0 +1,42 @@ +terraform { + required_providers { + oneuptime = { + source = "oneuptime/oneuptime" + version = "1.0.0" + } + } +} + +provider "oneuptime" { + oneuptime_url = var.oneuptime_url + api_key = var.api_key +} + +# Comprehensive CRUD test for incident_severity resource +resource "oneuptime_incident_severity" "test" { + project_id = var.project_id + name = var.severity_name + description = var.severity_description + color = var.severity_color + order = var.severity_order +} + +output "incident_severity_id" { + value = oneuptime_incident_severity.test.id +} + +output "incident_severity_name" { + value = oneuptime_incident_severity.test.name +} + +output "incident_severity_description" { + value = oneuptime_incident_severity.test.description +} + +output "incident_severity_color" { + value = oneuptime_incident_severity.test.color +} + +output "incident_severity_order" { + value = oneuptime_incident_severity.test.order +} diff --git a/E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/variables.tf b/E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/variables.tf new file mode 100644 index 0000000000..200678e51f --- /dev/null +++ b/E2E/Terraform/e2e-tests/tests/11-incident-severity-crud/variables.tf @@ -0,0 +1,39 @@ +variable "oneuptime_url" { + type = string + description = "OneUptime API URL" +} + +variable "api_key" { + type = string + description = "OneUptime API Key" + sensitive = true +} + +variable "project_id" { + type = string + description = "OneUptime Project ID" +} + +variable "severity_name" { + type = string + description = "Incident severity name" + default = "terraform-crud-test-severity" +} + +variable "severity_description" { + type = string + description = "Incident severity description" + default = "Initial description for CRUD test" +} + +variable "severity_color" { + type = string + description = "Incident severity color" + default = "#FFA500" +} + +variable "severity_order" { + type = number + description = "Incident severity order" + default = 100 +} diff --git a/Scripts/TerraformProvider/Core/ResourceGenerator.ts b/Scripts/TerraformProvider/Core/ResourceGenerator.ts index b1364888f9..a7dc9bd55b 100644 --- a/Scripts/TerraformProvider/Core/ResourceGenerator.ts +++ b/Scripts/TerraformProvider/Core/ResourceGenerator.ts @@ -1073,9 +1073,13 @@ func (r *${resourceTypeName}Resource) Delete(ctx context.Context, req resource.D terraformAttr.type === "string" && terraformAttr.isComplexObject ) { + // Try to parse as JSON first, but if it fails (e.g., for simple strings like "#FF0000"), + // fall back to sending the raw string value return `var ${fieldName.toLowerCase()}Data interface{} if err := json.Unmarshal([]byte(data.${fieldName}.ValueString()), &${fieldName.toLowerCase()}Data); err == nil { requestDataMap["${apiFieldName}"] = ${fieldName.toLowerCase()}Data + } else { + requestDataMap["${apiFieldName}"] = data.${fieldName}.ValueString() }`; } return `requestDataMap["${apiFieldName}"] = ${value}`; @@ -1279,9 +1283,14 @@ func (r *${resourceTypeName}Resource) Delete(ctx context.Context, req resource.D // ${fieldName} value is already set from the existing state }`; } else if (isComplexObject) { - // For complex object strings, convert API object response to JSON string + // For complex object strings, check if it's a wrapper object with _type and value fields + // (e.g., {"_type":"Version","value":"1.0.0"} or {"_type":"DateTime","value":"..."}) + // If so, extract the value; otherwise convert the entire object to JSON string return `if val, ok := ${responseValue}.(map[string]interface{}); ok { - if jsonBytes, err := json.Marshal(val); err == nil { + // Check if it's a wrapper object with value field (e.g., Version, DateTime types) + if innerVal, ok := val["value"].(string); ok { + ${fieldName} = types.StringValue(innerVal) + } else if jsonBytes, err := json.Marshal(val); err == nil { ${fieldName} = types.StringValue(string(jsonBytes)) } else { ${fieldName} = types.StringNull()