Skip to content

Commit

Permalink
fix: Added retry-after support to zpa api client (#240)
Browse files Browse the repository at this point in the history
* fix: Added retry-after support to zpa api client
* fix Readjusted makefile and github workflow
  • Loading branch information
willguibr authored May 6, 2024
1 parent e4ee548 commit 3ae5801
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 94 deletions.
124 changes: 62 additions & 62 deletions .github/workflows/zpa-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,73 +12,73 @@ on:
workflow_dispatch:

jobs:
zpa-qa1-tenants:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
goVersion: ["1.21"]
environment:
- ZPA_QA_TENANT01
- ZPA_QA_TENANT02
environment: ${{ matrix.environment }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
# zpa-qa1-tenants:
# runs-on: ubuntu-latest
# strategy:
# fail-fast: false
# matrix:
# goVersion: ["1.21"]
# environment:
# - ZPA_QA_TENANT01
# - ZPA_QA_TENANT02
# environment: ${{ matrix.environment }}
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# with:
# token: ${{ secrets.GITHUB_TOKEN }}

- 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: Clean existing Go modules
run: go clean -modcache
# - name: Clean existing Go modules
# run: go clean -modcache

- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
# - name: Cache Go modules
# uses: actions/cache@v4
# with:
# path: |
# ~/go/pkg/mod
# ~/.cache/go-build
# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
# restore-keys: |
# ${{ runner.os }}-go-

- 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: Install dependencies
run: go mod download
# - name: Install dependencies
# run: go mod download

- name: Run tests with retry
uses: nick-fields/retry@v2
with:
max_attempts: 3
timeout_minutes: 20
command: |
make test:unit
make test:unit:zpa
make sweep:zpa
make test:integration:zpa
env:
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 }}
ZPA_SDK_TEST_SWEEP: ${{ secrets.ZPA_SDK_TEST_SWEEP }}
OKTA_CLIENT_ORGURL: ${{ secrets.OKTA_CLIENT_ORGURL }}
OKTA_CLIENT_TOKEN: ${{ secrets.OKTA_CLIENT_TOKEN }}
# - name: Run tests with retry
# uses: nick-fields/retry@v2
# with:
# max_attempts: 3
# timeout_minutes: 20
# command: |
# make test:unit
# make test:unit:zpa
# make sweep:zpa
# make test:integration:zpa
# env:
# 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 }}
# ZPA_SDK_TEST_SWEEP: ${{ secrets.ZPA_SDK_TEST_SWEEP }}
# OKTA_CLIENT_ORGURL: ${{ secrets.OKTA_CLIENT_ORGURL }}
# OKTA_CLIENT_TOKEN: ${{ secrets.OKTA_CLIENT_TOKEN }}

- name: Publish test coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.out
fail_ci_if_error: true
# - name: Publish test coverage
# uses: codecov/codecov-action@v4
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# file: ./coverage.out
# fail_ci_if_error: true

# zpa-qa2-tenants:
# runs-on: ubuntu-latest
Expand Down Expand Up @@ -140,7 +140,7 @@ jobs:
# OKTA_CLIENT_TOKEN: ${{ secrets.OKTA_CLIENT_TOKEN }}

zpa-beta-tenants:
needs: [zpa-qa1-tenants]
# needs: [zpa-qa1-tenants]
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -208,7 +208,7 @@ jobs:
fail_ci_if_error: true

zpa-prod-tenants:
needs: [zpa-qa1-tenants, zpa-beta-tenants]
needs: [zpa-beta-tenants]
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

# 2.5.0 (May 6, 2024)

## Notes
- Golang: **v1.21**

### Enhancements

- [PR #240](https://github.com/zscaler/zscaler-sdk-go/pull/240) - Added new `Retry-After` header to ZPA API Client. Please see API Developer's documentation [here](https://help.zscaler.com/zpa/understanding-rate-limiting) for details.

# 2.4.35 (April 12, 2024)

## Notes
Expand Down
40 changes: 16 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ help:
@echo "$(COLOR_OK) make [command]$(COLOR_NONE)"
@echo ""
@echo "$(COLOR_WARNING)Available commands:$(COLOR_NONE)"
@echo "$(COLOR_OK) build Clean and build the Zscaler Golang SDK generated files$(COLOR_NONE)"
@echo "$(COLOR_OK) build Clean and build the Zscaler Golang SDK generated files$(COLOR_NONE)"
@echo "$(COLOR_WARNING)test$(COLOR_NONE)"
@echo "$(COLOR_OK) test:all Run all tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:zcon Run only zcon integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:zdx Run only zdx integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:zia Run only zia integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:zpa Run only zpa integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:integration Run only unit tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:unit Run only unit tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:all Run all tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:integration:zcon Run only zcon integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:integration:zdx Run only zdx integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:integration:zia Run only zia integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:integration:zpa Run only zpa integration tests$(COLOR_NONE)"
@echo "$(COLOR_OK) test:unit Run only unit tests$(COLOR_NONE)"


default: build
Expand Down Expand Up @@ -76,10 +75,6 @@ sweep\:zia:
@echo "$(COLOR_WARNING)WARNING: This will destroy infrastructure. Use only in development accounts.$(COLOR_NONE)"
ZIA_SDK_TEST_SWEEP=true go test ./zia/sweep -v -sweep=true


test:
make test:all

test\:all:
@echo "$(COLOR_ZSCALER)Running all tests...$(COLOR_NONE)"
@make test:integration:zcon
Expand All @@ -89,23 +84,24 @@ test\:all:

test\:integration\:zcon:
@echo "$(COLOR_ZSCALER)Running zcon integration tests...$(COLOR_NONE)"
go test -failfast -race ./zcon/... -race -coverprofile=coverage.out -covermode=atomic -v -parallel 20 -timeout 120m
go tool cover -html=coverage.out -o coverage.html
go test -v -race -cover -coverprofile=zconcoverage.out -covermode=atomic ./zcon/... -parallel 20 -timeout 60m
go tool cover -html=zconcoverage.out -o zconcoverage.html

test\:integration\:zdx:
@echo "$(COLOR_ZSCALER)Running zcon integration tests...$(COLOR_NONE)"
go test -failfast -race ./zdx/... -race -race -coverprofile=coverage.out -covermode=atomic -v -parallel 4 -timeout 30m
go tool cover -html=coverage.out -o coverage.html
go test -v -race -cover -coverprofile=zdxcoverage.out -covermode=atomic ./zdx/... -parallel 4 -timeout 60m
go tool cover -html=zdxcoverage.out -o zdxcoverage.html

test\:integration\:zpa:
@echo "$(COLOR_ZSCALER)Running zpa integration tests...$(COLOR_NONE)"
go test -failfast -race ./zpa/... -race -coverprofile=coverage.out -covermode=atomic -v -parallel 20 -timeout 120m
go tool cover -html=coverage.out -o coverage.html
@go test -v -failfast -race -cover -coverprofile=zpacoverage.out -covermode=atomic ./zpa/... -parallel 20 -timeout 60m
@go tool cover -html=zpacoverage.out -o zpacoverage.html


test\:integration\:zia:
@echo "$(COLOR_ZSCALER)Running zia integration tests...$(COLOR_NONE)"
go test -failfast -race ./zia/... -race -coverprofile=coverage.out -covermode=atomic -v -parallel 10 -timeout 120m
go tool cover -html=coverage.out -o coverage.html
go test -v -race -cover -coverprofile=ziacoverage.out -covermode=atomic ./zia/... -parallel 10 -timeout 60m
go tool cover -html=ziacoverage.out -o ziacoverage.html

test\:unit:
@echo "$(COLOR_OK)Running unit tests...$(COLOR_NONE)"
Expand Down Expand Up @@ -166,10 +162,6 @@ zconActivator:
@go build -o $(DESTINATION)/zconActivator ./zcon/services/activation_cli/zconActivator.go
zconActivator

.PHONY: fmt
fmt: check-fmt # Format the code
@$(GOFMT) -l -w $$(find . -name '*.go' |grep -v vendor) > /dev/null

check-fmt:
@which $(GOFMT) > /dev/null || GO111MODULE=on go install mvdan.cc/gofumpt@latest

Expand Down
11 changes: 10 additions & 1 deletion docs/guides/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,19 @@ Track all Zscaler SDK GO releases. New resources, features, and bug fixes will b

---

``Last updated: v2.4.35``
``Last updated: v2.5.0``

---

# 2.5.0 (May 6, 2024)

## Notes
- Golang: **v1.21**

### Enhancements

- [PR #240](https://github.com/zscaler/zscaler-sdk-go/pull/240) - Added new `Retry-After` header to ZPA API Client. Please see API Developer's documentation [here](https://help.zscaler.com/zpa/understanding-rate-limiting) for details.

# 2.4.35 (April 12, 2024)

## Notes
Expand Down
8 changes: 6 additions & 2 deletions zcon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,15 @@ func (c *Client) GetContentType() string {
}

func getRetryAfter(resp *http.Response, l logger.Logger) time.Duration {
if s, ok := resp.Header["Retry-After"]; ok {
if sleep, err := strconv.ParseInt(s[0], 10, 64); err == nil {
if s := resp.Header.Get("Retry-After"); s != "" {
if sleep, err := strconv.ParseInt(s, 10, 64); err == nil {
l.Printf("[INFO] got Retry-After from header:%s\n", s)
return time.Second * time.Duration(sleep)
} else {
dur, err := time.ParseDuration(s)
if err == nil {
return dur
}
l.Printf("[INFO] error getting Retry-After from header:%s\n", err)
}
}
Expand Down
8 changes: 6 additions & 2 deletions zia/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,15 @@ func (c *Client) GetContentType() string {
}

func getRetryAfter(resp *http.Response, l logger.Logger) time.Duration {
if s, ok := resp.Header["Retry-After"]; ok {
if sleep, err := strconv.ParseInt(s[0], 10, 64); err == nil {
if s := resp.Header.Get("Retry-After"); s != "" {
if sleep, err := strconv.ParseInt(s, 10, 64); err == nil {
l.Printf("[INFO] got Retry-After from header:%s\n", s)
return time.Second * time.Duration(sleep)
} else {
dur, err := time.ParseDuration(s)
if err == nil {
return dur
}
l.Printf("[INFO] error getting Retry-After from header:%s\n", err)
}
}
Expand Down
10 changes: 7 additions & 3 deletions zpa/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,14 @@ func (c *Config) GetHTTPClient() *http.Client {
retryableClient.Backoff = func(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
if resp != nil {
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode == http.StatusServiceUnavailable {
// TODO: ask backend to implement such header, instead of using the logic below
if s, ok := resp.Header["Retry-After"]; ok {
if sleep, err := strconv.ParseInt(s[0], 10, 64); err == nil {
if s := resp.Header.Get("Retry-After"); s != "" {
if sleep, err := strconv.ParseInt(s, 10, 64); err == nil {
return time.Second * time.Duration(sleep)
} else {
dur, err := time.ParseDuration(s)
if err == nil {
return dur
}
}
}
}
Expand Down

0 comments on commit 3ae5801

Please sign in to comment.