Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

95 changes: 7 additions & 88 deletions internal/resources/zero_trust_gateway_certificate/v4_to_v5.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import (
"github.com/cloudflare/tf-migrate/internal"
"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"

"github.com/cloudflare/tf-migrate/internal/transform"
tfhcl "github.com/cloudflare/tf-migrate/internal/transform/hcl"
"github.com/cloudflare/tf-migrate/internal/transform/state"
)

type V4ToV5Migrator struct {
Expand Down Expand Up @@ -45,92 +43,13 @@ func (m *V4ToV5Migrator) TransformConfig(ctx *transform.Context, block *hclwrite
}

func (m *V4ToV5Migrator) TransformState(ctx *transform.Context, stateJSON gjson.Result, resourcePath, resourceName string) (string, error) {
result := stateJSON.String()

if stateJSON.Get("resources").Exists() {
return m.transformFullState(ctx, result, stateJSON)
}

if !stateJSON.Exists() || !stateJSON.Get("attributes").Exists() {
return result, nil
}

result = m.transformSingleInstance(ctx, result, stateJSON, resourceName)

return result, nil
// State transformation is handled by the provider's StateUpgraders (MoveState/UpgradeState)
// The moved block generated in TransformConfig triggers the provider's migration logic
// This function is a no-op for zero_trust_gateway_certificate migration
return stateJSON.String(), nil
}

func (m *V4ToV5Migrator) transformFullState(ctx *transform.Context, result string, stateJSON gjson.Result) (string, error) {
resources := stateJSON.Get("resources")
if !resources.Exists() {
return result, nil
}

resources.ForEach(func(key, resource gjson.Result) bool {
resourceType := resource.Get("type").String()

if !m.CanHandle(resourceType) {
return true
}

resourceName := resource.Get("name").String()
instances := resource.Get("instances")
instances.ForEach(func(instKey, instance gjson.Result) bool {
instPath := "resources." + key.String() + ".instances." + instKey.String()

attrs := instance.Get("attributes")
if attrs.Exists() {
instJSON := instance.String()
transformedInst := m.transformSingleInstance(ctx, instJSON, instance, resourceName)
transformedInstParsed := gjson.Parse(transformedInst)
result, _ = sjson.SetRaw(result, instPath, transformedInstParsed.Raw)
}
return true
})

return true
})

return result, nil
}

func (m *V4ToV5Migrator) transformSingleInstance(ctx *transform.Context, result string, instance gjson.Result, resourceName string) string {
attrs := instance.Get("attributes")

// Remove v4-only fields that don't exist in v5 or changed behavior:
result = state.RemoveFields(result, "attributes", attrs, "custom", "gateway_managed", "qs_pack_id")

// Handle validity_period_days:
// - If it was explicitly set in v4 config: keep it in state (convert to Int64)
// - If it was just the v4 default: remove it from state
validityPeriodDays := instance.Get("attributes.validity_period_days")
if validityPeriodDays.Exists() {
wasExplicitlySet := false
if ctx.CFGFiles != nil {
for _, cfgFile := range ctx.CFGFiles {
body := cfgFile.Body()
for _, block := range body.Blocks() {
if block.Type() == "resource" && len(block.Labels()) >= 2 {
if block.Labels()[0] == "cloudflare_zero_trust_gateway_certificate" && block.Labels()[1] == resourceName {
if tfhcl.HasAttribute(block.Body(), "validity_period_days") {
wasExplicitlySet = true
break
}
}
}
}
if wasExplicitlySet {
break
}
}
}

if wasExplicitlySet {
result, _ = sjson.Set(result, "attributes.validity_period_days", state.ConvertToFloat64(validityPeriodDays))
} else {
result = state.RemoveFields(result, "attributes", attrs, "validity_period_days")
}
}

return result
// UsesProviderStateUpgrader indicates that this resource uses provider-based state migration
func (m *V4ToV5Migrator) UsesProviderStateUpgrader() bool {
return true
}
Loading