diff --git a/CHANGELOG.md b/CHANGELOG.md index d329e6f..0c43a40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.3.6 (January, 5 2025) + +### Notes + +- Release date: **(January, 5 2025)** +- Supported Terraform version: **v1.x.x** + +### Bug Fixes +- [PR #244](https://github.com/zscaler/zscaler-terraformer/pull/244). Fixed ZIA import resources for: `zia_dlp_web_rules` to exclude attributes `auditor`, `icap_server`, and `notification_template`, when not populated. +- [PR #244](https://github.com/zscaler/zscaler-terraformer/pull/244). Fixed ZIA import resources for: `zia_firewall_filtering_rule` to reformat the attribute values `dest_countries` and `source_countries` during HCL generation. +- [PR #244](https://github.com/zscaler/zscaler-terraformer/pull/244). Upgraded tool to GO SDK v2.74.2 to fix ZPA import resource `zpa_service_edge_group`. + ## 1.3.5 (November, 7 2024) ### Notes diff --git a/cmd/generate.go b/cmd/generate.go index 1b61d82..ed19152 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -1098,6 +1098,7 @@ func generate(cmd *cobra.Command, writer io.Writer, resourceType string) { resourceCount = len(items) m, _ := json.Marshal(items) _ = json.Unmarshal(m, &jsonStructData) + case "zia_url_filtering_rules": if api.ZIA == nil { log.Fatal("ZIA client is not initialized") @@ -1340,7 +1341,7 @@ func generate(cmd *cobra.Command, writer io.Writer, resourceType string) { } } else if resourceType == "zia_dlp_notification_templates" && helpers.IsInList(attrName, []string{"subject", "plain_text_message", "html_message"}) { valueStr := strings.ReplaceAll(value.(string), "$", "$$") - formattedValue := formatHeredoc(valueStr) + formattedValue := helpers.FormatHeredoc(valueStr) switch attrName { case "html_message", "plain_text_message": output += fmt.Sprintf(" %s = <<-EOT\n%sEOT\n\n", attrName, formattedValue) @@ -1411,17 +1412,3 @@ func generate(cmd *cobra.Command, writer io.Writer, resourceType string) { fmt.Fprint(writer, output) } - -func formatHeredoc(value string) string { - lines := strings.Split(value, "\n") - formatted := "" - for i, line := range lines { - trimmedLine := strings.TrimSpace(line) - if trimmedLine != "" { - formatted += fmt.Sprintf("%s\n", trimmedLine) - } else if i != len(lines)-1 { - formatted += "\n" - } - } - return formatted -} diff --git a/docs/guides/release-notes.md b/docs/guides/release-notes.md index d6408d9..f33ce23 100644 --- a/docs/guides/release-notes.md +++ b/docs/guides/release-notes.md @@ -12,10 +12,22 @@ Track all Zscaler Terraformer Tool releases. New resources, features, and bug fi --- -``Last updated: v1.3.5`` +``Last updated: v1.3.6`` --- +## 1.3.6 (January, 5 2025) + +### Notes + +- Release date: **(January, 5 2025)** +- Supported Terraform version: **v1.x.x** + +### Bug Fixes +- [PR #244](https://github.com/zscaler/zscaler-terraformer/pull/244). Fixed ZIA import resources for: `zia_dlp_web_rules` to exclude attributes `auditor`, `icap_server`, and `notification_template`, when not populated. +- [PR #244](https://github.com/zscaler/zscaler-terraformer/pull/244). Fixed ZIA import resources for: `zia_firewall_filtering_rule` to reformat the attribute values `dest_countries` and `source_countries` during HCL generation. +- [PR #244](https://github.com/zscaler/zscaler-terraformer/pull/244). Upgraded tool to GO SDK v2.74.2 to fix ZPA import resource `zpa_service_edge_group`. + ## 1.3.5 (November, 7 2024) ### Notes diff --git a/go.mod b/go.mod index cfb5b71..f7e6b62 100644 --- a/go.mod +++ b/go.mod @@ -8,13 +8,13 @@ require ( github.com/google/uuid v1.6.0 github.com/hashicorp/hc-install v0.9.0 github.com/hashicorp/terraform-exec v0.21.0 - github.com/hashicorp/terraform-json v0.24.0 + github.com/hashicorp/terraform-json v0.23.0 github.com/iancoleman/strcase v0.3.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 - github.com/zclconf/go-cty v1.15.1 - github.com/zscaler/zscaler-sdk-go/v2 v2.732.0 + github.com/zclconf/go-cty v1.15.0 + github.com/zscaler/zscaler-sdk-go/v2 v2.74.2 ) require ( @@ -33,7 +33,7 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect - github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect diff --git a/go.sum b/go.sum index 1b2b225..9808392 100644 --- a/go.sum +++ b/go.sum @@ -61,14 +61,14 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q= -github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow= +github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= +github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-plugin-sdk v1.17.2 h1:V7DUR3yBWFrVB9z3ddpY7kiYVSsq4NYR67NiTs93NQo= github.com/hashicorp/terraform-plugin-sdk v1.17.2/go.mod h1:wkvldbraEMkz23NxkkAsFS88A1R9eUiooiaUZyS6TLw= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -137,16 +137,17 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/zclconf/go-cty v1.15.1 h1:RgQYm4j2EvoBRXOPxhUvxPzRrGDo1eCOhHXuGfrj5S0= -github.com/zclconf/go-cty v1.15.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -github.com/zscaler/zscaler-sdk-go/v2 v2.732.0 h1:oyESzPJJswG9dTSH0VcCeZH1ebYUmhIOKeTQg0sLu+w= -github.com/zscaler/zscaler-sdk-go/v2 v2.732.0/go.mod h1:ugDudbyESUrANGw74moJypgVnWuOyLm8NyIJgfUzNNo= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zscaler/zscaler-sdk-go/v2 v2.74.2 h1:akUaVrnqLNWFBx5GK++PirbPJTdm/6jiAh4qm5fdTqI= +github.com/zscaler/zscaler-sdk-go/v2 v2.74.2/go.mod h1:4ZS4vlk8HKciHYJ6n1vnN2xXus5ir388p7K3VJSRkL8= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= @@ -155,8 +156,8 @@ golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUF golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/teraformutils/helpers/helpers.go b/teraformutils/helpers/helpers.go index 2057673..861150d 100644 --- a/teraformutils/helpers/helpers.go +++ b/teraformutils/helpers/helpers.go @@ -43,21 +43,26 @@ func IsInList(item string, list []string) bool { // TypeSetBlock generates HCL for TypeSet attributes like notification_template, auditor, icap_server. func TypeSetBlock(blockName string, blockData interface{}) string { - output := blockName + " {\n" + output := "" + switch blockData := blockData.(type) { case map[string]interface{}: - if id, ok := blockData["id"].(float64); ok { - output += fmt.Sprintf("id = %d\n", int64(id)) + // Check if the ID exists and is valid + if id, ok := blockData["id"].(float64); ok && id != 0 { + output += fmt.Sprintf("%s {\n id = %d\n}\n", blockName, int64(id)) } case []interface{}: - // If it's an array, process each item. + // Process each item in the array for _, item := range blockData { if itemMap, ok := item.(map[string]interface{}); ok { - output += TypeSetBlock(blockName, itemMap) + nestedBlock := TypeSetBlock(blockName, itemMap) + if nestedBlock != "" { + output += nestedBlock + } } } } - output += "}\n" + return output } @@ -395,3 +400,17 @@ func HandleZIAError(responseBody []byte) (bool, string) { } return false, "" } + +func FormatHeredoc(value string) string { + lines := strings.Split(value, "\n") + formatted := "" + for i, line := range lines { + trimmedLine := strings.TrimSpace(line) + if trimmedLine != "" { + formatted += fmt.Sprintf("%s\n", trimmedLine) + } else if i != len(lines)-1 { + formatted += "\n" + } + } + return formatted +} diff --git a/teraformutils/nesting/nesting.go b/teraformutils/nesting/nesting.go index 625f767..89b2204 100644 --- a/teraformutils/nesting/nesting.go +++ b/teraformutils/nesting/nesting.go @@ -66,8 +66,10 @@ func NestBlocks(resourceType string, schemaBlock *tfjson.SchemaBlock, structData if helpers.IsInList(resourceType, []string{"zia_dlp_web_rules"}) && helpers.IsInList(block, []string{ "notification_template", "auditor", "icap_server", }) { - // Use the new TypeSetBlock helper. - output += helpers.TypeSetBlock(block, structData[apiBlock]) + blockOutput := helpers.TypeSetBlock(block, structData[apiBlock]) + if blockOutput != "" { + output += blockOutput + } continue } @@ -384,6 +386,27 @@ func WriteAttrLine(key string, value interface{}, usedInBlock bool) string { return "" } + // Handle `dest_countries` and `source_countries` for `zia_firewall_filtering_rule` + if helpers.IsInList(key, []string{"dest_countries", "source_countries"}) { + if countryList, ok := value.([]string); ok { + // Strip the "COUNTRY_" prefix + for i, country := range countryList { + countryList[i] = strings.TrimPrefix(country, "COUNTRY_") + } + return fmt.Sprintf("%s = [%s]\n", key, formatList(countryList)) + } + } + + // Handle multiline strings with Heredoc + if strValue, ok := value.(string); ok { + if strings.Contains(strValue, "\n") { + // Use your existing formatHeredoc function + return fmt.Sprintf("%s = <