diff --git a/.github/workflows/zia-test.yml b/.github/workflows/zia-test.yml index f5d5b58..eee5159 100644 --- a/.github/workflows/zia-test.yml +++ b/.github/workflows/zia-test.yml @@ -18,152 +18,85 @@ on: workflow_dispatch: jobs: - zia-zsbeta-tests: - environment: ZIA_ZSBETA - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - goVersion: ["1.21"] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.goVersion }} - - - name: Set Go env - run: | - echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV - echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - - - name: Setup Go Tools - run: make tools - - - name: Download Go Dependencies - run: | - go mod tidy && go mod vendor - - - name: Setup Go Tools - run: make tools - - - name: Check Formatting - run: make fmtcheck - - # - name: Vet Code - # run: make vet - - - name: Lint Code - run: make lint - - - name: Check Build - run: make build - - - name: Run tests with retry - uses: nick-fields/retry@v3 - with: - max_attempts: 3 - timeout_minutes: 120 - command: | - make sweep - make test:integration:zia - make sweep - - env: - ZIA_USERNAME: ${{ secrets.ZIA_USERNAME }} - ZIA_PASSWORD: ${{ secrets.ZIA_PASSWORD }} - ZIA_API_KEY: ${{ secrets.ZIA_API_KEY }} - ZIA_CLOUD: ${{ secrets.ZIA_CLOUD }} - ZIA_SANDBOX_TOKEN: ${{ secrets.ZIA_SANDBOX_TOKEN }} - ZPA_CLIENT_ID: ${{ secrets.ZPA_CLIENT_ID }} - ZPA_CLIENT_SECRET: ${{ secrets.ZPA_CLIENT_SECRET }} - ZPA_CUSTOMER_ID: ${{ secrets.ZPA_CUSTOMER_ID }} - ZPA_CLOUD: ${{ secrets.ZPA_CLOUD }} - TF_ACC: ${{ secrets.TF_ACC }} - ZIA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZIA_ACC_TEST_FORCE_SWEEPERS }} + # zia-zsbeta-tests: + # environment: ZIA_ZSBETA + # runs-on: ubuntu-latest + # strategy: + # fail-fast: false + # matrix: + # goVersion: ["1.21"] + # steps: + # - name: Checkout code + # uses: actions/checkout@v4 - zia-test-tenants: - needs: [zia-zsbeta-tests] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - goVersion: ["1.21"] - environment: - # - ZIA_ZSCLOUD - - ZIA_ZS0 - # - ZIA_ZS1 - # - ZIA_ZS2 - # - ZIA_ZS3 - environment: ${{ matrix.environment }} - steps: - - name: Checkout code - uses: actions/checkout@v4 + # - name: Setup Go + # uses: actions/setup-go@v5 + # with: + # go-version: ${{ matrix.goVersion }} - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.goVersion }} + # - name: Set Go env + # run: | + # echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV + # echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - - name: Set Go env - run: | - echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV - echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + # - name: Setup Go Tools + # run: make tools - - name: Setup Go Tools - run: make tools + # - name: Download Go Dependencies + # run: | + # go mod tidy && go mod vendor - - name: Download Go Dependencies - run: | - go mod tidy && go mod vendor + # - name: Setup Go Tools + # run: make tools - - name: Setup Go Tools - run: make tools + # - name: Check Formatting + # run: make fmtcheck - - name: Check Formatting - run: make fmtcheck + # # - name: Vet Code + # # run: make vet - # - name: Vet Code - # run: make vet + # - name: Lint Code + # run: make lint - - name: Lint Code - run: make lint + # - name: Check Build + # run: make build - - name: Check Build - run: make build + # - name: Run tests with retry + # uses: nick-fields/retry@v3 + # with: + # max_attempts: 3 + # timeout_minutes: 120 + # command: | + # make sweep + # make test:integration:zia + # make sweep - - name: Run tests with retry on Ubuntu - uses: nick-fields/retry@v3 - with: - max_attempts: 3 - timeout_minutes: 120 - command: | - make sweep - make test:integration:zscalerone - make sweep - env: - ZIA_USERNAME: ${{ secrets.ZIA_USERNAME }} - ZIA_PASSWORD: ${{ secrets.ZIA_PASSWORD }} - ZIA_API_KEY: ${{ secrets.ZIA_API_KEY }} - ZIA_CLOUD: ${{ secrets.ZIA_CLOUD }} - ZIA_SANDBOX_TOKEN: ${{ secrets.ZIA_SANDBOX_TOKEN }} - ZPA_CLIENT_ID: ${{ secrets.ZPA_CLIENT_ID }} - ZPA_CLIENT_SECRET: ${{ secrets.ZPA_CLIENT_SECRET }} - ZPA_CUSTOMER_ID: ${{ secrets.ZPA_CUSTOMER_ID }} - ZPA_CLOUD: ${{ secrets.ZPA_CLOUD }} - TF_ACC: ${{ secrets.TF_ACC }} - ZIA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZIA_ACC_TEST_FORCE_SWEEPERS }} + # env: + # ZIA_USERNAME: ${{ secrets.ZIA_USERNAME }} + # ZIA_PASSWORD: ${{ secrets.ZIA_PASSWORD }} + # ZIA_API_KEY: ${{ secrets.ZIA_API_KEY }} + # ZIA_CLOUD: ${{ secrets.ZIA_CLOUD }} + # ZIA_SANDBOX_TOKEN: ${{ secrets.ZIA_SANDBOX_TOKEN }} + # ZPA_CLIENT_ID: ${{ secrets.ZPA_CLIENT_ID }} + # ZPA_CLIENT_SECRET: ${{ secrets.ZPA_CLIENT_SECRET }} + # ZPA_CUSTOMER_ID: ${{ secrets.ZPA_CUSTOMER_ID }} + # ZPA_CLOUD: ${{ secrets.ZPA_CLOUD }} + # TF_ACC: ${{ secrets.TF_ACC }} + # ZIA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZIA_ACC_TEST_FORCE_SWEEPERS }} - # zia-zscalerone-test: + # zia-test-tenants: + # needs: [zia-zsbeta-tests] # runs-on: ubuntu-latest # strategy: # fail-fast: false # matrix: # goVersion: ["1.21"] # environment: - # - ZIA_ZS1 + # # - ZIA_ZSCLOUD + # - ZIA_ZS0 + # # - ZIA_ZS1 + # # - ZIA_ZS2 + # # - ZIA_ZS3 # environment: ${{ matrix.environment }} # steps: # - name: Checkout code @@ -205,7 +138,7 @@ jobs: # uses: nick-fields/retry@v3 # with: # max_attempts: 3 - # timeout_minutes: 45 # Adjust as needed + # timeout_minutes: 120 # command: | # make sweep # make test:integration:zscalerone @@ -223,14 +156,14 @@ jobs: # TF_ACC: ${{ secrets.TF_ACC }} # ZIA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZIA_ACC_TEST_FORCE_SWEEPERS }} - # zia-zscalertwo-test: + # zia-zscalerone-test: # runs-on: ubuntu-latest # strategy: # fail-fast: false # matrix: # goVersion: ["1.21"] # environment: - # - ZIA_ZS2 + # - ZIA_ZS1 # environment: ${{ matrix.environment }} # steps: # - name: Checkout code @@ -272,10 +205,10 @@ jobs: # uses: nick-fields/retry@v3 # with: # max_attempts: 3 - # timeout_minutes: 120 + # timeout_minutes: 45 # Adjust as needed # command: | # make sweep - # make test:integration:zia + # make test:integration:zscalerone # make sweep # env: # ZIA_USERNAME: ${{ secrets.ZIA_USERNAME }} @@ -290,6 +223,73 @@ jobs: # TF_ACC: ${{ secrets.TF_ACC }} # ZIA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZIA_ACC_TEST_FORCE_SWEEPERS }} + zia-zscalertwo-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + goVersion: ["1.21"] + environment: + - ZIA_ZS2 + environment: ${{ matrix.environment }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.goVersion }} + + - name: Set Go env + run: | + echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + + - name: Setup Go Tools + run: make tools + + - name: Download Go Dependencies + run: | + go mod tidy && go mod vendor + + - name: Setup Go Tools + run: make tools + + - name: Check Formatting + run: make fmtcheck + + # - name: Vet Code + # run: make vet + + - name: Lint Code + run: make lint + + - name: Check Build + run: make build + + - name: Run tests with retry on Ubuntu + uses: nick-fields/retry@v3 + with: + max_attempts: 3 + timeout_minutes: 120 + command: | + make sweep + make test:integration:zia + make sweep + env: + ZIA_USERNAME: ${{ secrets.ZIA_USERNAME }} + ZIA_PASSWORD: ${{ secrets.ZIA_PASSWORD }} + ZIA_API_KEY: ${{ secrets.ZIA_API_KEY }} + ZIA_CLOUD: ${{ secrets.ZIA_CLOUD }} + ZIA_SANDBOX_TOKEN: ${{ secrets.ZIA_SANDBOX_TOKEN }} + ZPA_CLIENT_ID: ${{ secrets.ZPA_CLIENT_ID }} + ZPA_CLIENT_SECRET: ${{ secrets.ZPA_CLIENT_SECRET }} + ZPA_CUSTOMER_ID: ${{ secrets.ZPA_CUSTOMER_ID }} + ZPA_CLOUD: ${{ secrets.ZPA_CLOUD }} + TF_ACC: ${{ secrets.TF_ACC }} + ZIA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZIA_ACC_TEST_FORCE_SWEEPERS }} + - name: Publish test coverage uses: codecov/codecov-action@v4 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f1bba7..48d6533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 3.0.5 (October, 4 2024) + +### Notes + +- Release date: **(October, 4 2024)** +- Supported Terraform version: **v1.x** + +### Bug Fixes + +- [PR #373](https://github.com/zscaler/terraform-provider-zia/pull/373) - The resource `zia_forwarding_control_rule` now pauses for 60 seconds before proceeding with the create or update process whenever the `forward_method` attribute is set to `ZPA`. In case of a failure related to resource synchronization, the provider will retry the resource creation or update up to 3 times, waiting 30 seconds between each retry. This behavior ensures that ZIA and ZPA have sufficient time to synchronize and replicate the necessary resource IDs, reducing the risk of transient errors during provisioning. + **NOTE** This retry mechanism helps to automatically overcome temporary latency without manual intervention. This behavior does not affect forwarding rules configured with other forward_methods such as `DIRECT`. + ## 3.0.4 (September, 6 2024) ### Notes diff --git a/GNUmakefile b/GNUmakefile index bfdb8e8..dd241a4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -196,14 +196,14 @@ test\:integration\:zscalertwo: build13: GOOS=$(shell go env GOOS) build13: GOARCH=$(shell go env GOARCH) ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10... -build13: DESTINATION=$(APPDATA)/terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.4/$(GOOS)_$(GOARCH) +build13: DESTINATION=$(APPDATA)/terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.5/$(GOOS)_$(GOARCH) else -build13: DESTINATION=$(HOME)/.terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.4/$(GOOS)_$(GOARCH) +build13: DESTINATION=$(HOME)/.terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.5/$(GOOS)_$(GOARCH) endif build13: fmtcheck @echo "==> Installing plugin to $(DESTINATION)" @mkdir -p $(DESTINATION) - go build -o $(DESTINATION)/terraform-provider-zia_v3.0.4 + go build -o $(DESTINATION)/terraform-provider-zia_v3.0.5 coverage: test @echo "✓ Opening coverage for unit tests ..." diff --git a/docs/guides/release-notes.md b/docs/guides/release-notes.md index 7cb631e..fda0462 100644 --- a/docs/guides/release-notes.md +++ b/docs/guides/release-notes.md @@ -12,10 +12,22 @@ description: |- Track all ZIA Terraform provider's releases. New resources, features, and bug fixes will be tracked here. --- -``Last updated: v3.0.4`` +``Last updated: v3.0.5`` --- +## 3.0.5 (October, 4 2024) + +### Notes + +- Release date: **(October, 4 2024)** +- Supported Terraform version: **v1.x** + +### Bug Fixes + +- [PR #373](https://github.com/zscaler/terraform-provider-zia/pull/373) - The resource `zia_forwarding_control_rule` now pauses for 60 seconds before proceeding with the create or update process whenever the `forward_method` attribute is set to `ZPA`. In case of a failure related to resource synchronization, the provider will retry the resource creation or update up to 3 times, waiting 30 seconds between each retry. This behavior ensures that ZIA and ZPA have sufficient time to synchronize and replicate the necessary resource IDs, reducing the risk of transient errors during provisioning. + **NOTE** This retry mechanism helps to automatically overcome temporary latency without manual intervention. This behavior does not affect forwarding rules configured with other forward_methods such as `DIRECT`. + ## 3.0.4 (September, 6 2024) ### Notes diff --git a/docs/resources/zia_forwarding_control_rule.md b/docs/resources/zia_forwarding_control_rule.md index 90eda4b..0184458 100644 --- a/docs/resources/zia_forwarding_control_rule.md +++ b/docs/resources/zia_forwarding_control_rule.md @@ -10,6 +10,11 @@ description: |- The **zia_forwarding_control_rule** resource allows the creation and management of ZIA Forwarding Control rules in the Zscaler Internet Access. +⚠️ **WARNING:** - [PR #373](https://github.com/zscaler/terraform-provider-zia/pull/373) - The resource `zia_forwarding_control_rule` now pauses for 60 seconds before proceeding with the create or update process whenever the `forward_method` attribute is set to `ZPA`. In case of a failure related to resource synchronization, the provider will retry the resource creation or update up to 3 times, waiting 30 seconds between each retry. This behavior ensures that ZIA and ZPA have sufficient time to synchronize and replicate the necessary resource IDs, reducing the risk of transient errors during provisioning. + + **NOTE**: This retry mechanism helps to automatically overcome temporary latency without manual intervention. This behavior does not affect forwarding rules configured with other forward_methods such as `DIRECT`. + + ## Example Usage - DIRECT Forwarding Method ```hcl diff --git a/go.mod b/go.mod index 7ec3e3d..53bc811 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,8 @@ module github.com/zscaler/terraform-provider-zia/v3 -go 1.21 -toolchain go1.22.5 +go 1.22 + +toolchain go1.23.1 require ( github.com/biter777/countries v1.7.5 @@ -10,7 +11,7 @@ require ( github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/terraform-plugin-sdk v1.17.2 github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 - github.com/zscaler/zscaler-sdk-go/v2 v2.72.2 + github.com/zscaler/zscaler-sdk-go/v2 v2.72.3 ) require ( @@ -59,7 +60,7 @@ require ( golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect diff --git a/go.sum b/go.sum index 19dc1c4..54a7298 100644 --- a/go.sum +++ b/go.sum @@ -388,8 +388,8 @@ github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgr github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= -github.com/zscaler/zscaler-sdk-go/v2 v2.72.2 h1:et3zoAHVllxJjGjJXucC88L45ZvIsxytAiHYxf4DbR0= -github.com/zscaler/zscaler-sdk-go/v2 v2.72.2/go.mod h1:dgtdfvnrFyuv1X3Knv5cjW1DNnQ3z/a4lU3uoYnxwcE= +github.com/zscaler/zscaler-sdk-go/v2 v2.72.3 h1:tkevJxm0QjZMuw2OQJBG12P5/xjQIbhcgLPo+6JOrtA= +github.com/zscaler/zscaler-sdk-go/v2 v2.72.3/go.mod h1:DW8JW8Cv2uxsfdlPN/Szk+CX9/nPyjhk/aERtTbJVYo= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -551,8 +551,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/zia/resource_zia_forwarding_control_rule.go b/zia/resource_zia_forwarding_control_rule.go index 9d32b3b..7683948 100644 --- a/zia/resource_zia_forwarding_control_rule.go +++ b/zia/resource_zia_forwarding_control_rule.go @@ -247,7 +247,32 @@ func resourceForwardingControlRuleCreate(d *schema.ResourceData, m interface{}) return err } - resp, err := forwarding_rules.Create(service, &req) + forwardMethod := d.Get("forward_method").(string) + if forwardMethod == "ZPA" { + // Sleep for 60 seconds before invoking Create + time.Sleep(60 * time.Second) + } + + // Retry logic in case of specific error + var resp *forwarding_rules.ForwardingRules + var err error + for i := 0; i < 3; i++ { + resp, err = forwarding_rules.Create(service, &req) + if err == nil { + break + } + + if forwardMethod == "ZPA" { + if respErr, ok := err.(*client.ErrorResponse); ok && respErr.Response.StatusCode == 400 && + strings.Contains(respErr.Message, "is no longer an active Source IP Anchored App Segment") { + log.Printf("[WARN] Received error indicating resource is no longer active. Retrying...\n") + time.Sleep(30 * time.Second) // Wait for 30 seconds before retrying + continue + } + } + return err + } + if err != nil { return err } @@ -411,9 +436,31 @@ func resourceForwardingControlRuleUpdate(d *schema.ResourceData, m interface{}) return nil } } - if _, err := forwarding_rules.Update(service, id, &req); err != nil { + + forwardMethod := d.Get("forward_method").(string) + if forwardMethod == "ZPA" { + // Sleep for 60 seconds before invoking Update + time.Sleep(60 * time.Second) + } + + // Retry logic in case of specific error + for i := 0; i < 3; i++ { + _, err := forwarding_rules.Update(service, id, &req) + if err == nil { + break + } + + if forwardMethod == "ZPA" { + if respErr, ok := err.(*client.ErrorResponse); ok && respErr.Response.StatusCode == 400 && + strings.Contains(respErr.Message, "is no longer an active Source IP Anchored App Segment") { + log.Printf("[WARN] Received error indicating resource is no longer active. Retrying...\n") + time.Sleep(30 * time.Second) // Wait for 30 seconds before retrying + continue + } + } return err } + // Sleep for 2 seconds before potentially triggering the activation time.Sleep(2 * time.Second) diff --git a/zia/resource_zia_forwarding_control_zpa_gateway.go b/zia/resource_zia_forwarding_control_zpa_gateway.go index 8bb0b81..45bf340 100644 --- a/zia/resource_zia_forwarding_control_zpa_gateway.go +++ b/zia/resource_zia_forwarding_control_zpa_gateway.go @@ -131,6 +131,7 @@ func resourceForwardingControlZPAGatewayCreate(d *schema.ResourceData, m interfa if err != nil { return err } + log.Printf("[INFO] Created forwarding control zpa gateway request. ID: %v\n", resp) d.SetId(strconv.Itoa(resp.ID)) _ = d.Set("gateway_id", resp.ID)