Skip to content

Commit

Permalink
feat: 429 retries
Browse files Browse the repository at this point in the history
  • Loading branch information
1riatsila1 committed Sep 19, 2024
1 parent c54b26f commit 97a8d9c
Show file tree
Hide file tree
Showing 26 changed files with 398 additions and 304 deletions.
5 changes: 5 additions & 0 deletions pkg/config-api-provider/provider/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package config

const (
MaxRetriesFor429 = 10
)
3 changes: 2 additions & 1 deletion pkg/config-api-provider/provider/data-sources/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -91,7 +92,7 @@ func (d *groupDataSource) Read(ctx context.Context, req datasource.ReadRequest,
request = request.Uid(*state.Filter.GroupID)
}

groupResponse, _, err := request.Execute()
groupResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(groupResponse.Groups) != 1 {
resp.Diagnostics.AddError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -70,10 +71,10 @@ func (d *sensorGroupAssignmentDataSource) Read(ctx context.Context, req datasour
return
}

sensorGroupAssignmentResponse, _, err := d.client.ConfigurationAPI.
request := d.client.ConfigurationAPI.
GetConfigurationAppV1SensorGroupAssignmentsGet(context.Background()).
Uid(state.Filter.SensorGroupAssignmentID).
Execute()
Uid(state.Filter.SensorGroupAssignmentID)
sensorGroupAssignmentResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(sensorGroupAssignmentResponse.SensorGroupAssignments) != 1 {
resp.Diagnostics.AddError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -95,10 +96,10 @@ func (d *wiredNetworkDataSource) Read(ctx context.Context, req datasource.ReadRe
return
}

networkResponse, _, err := d.client.ConfigurationAPI.
request := d.client.ConfigurationAPI.
GetConfigurationAppV1WiredNetworksGet(context.Background()).
Uid(state.Filter.WiredNetworkID).
Execute()
Uid(state.Filter.WiredNetworkID)
networkResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(networkResponse.WiredNetworks) != 1 {
resp.Diagnostics.AddError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -103,10 +104,10 @@ func (d *wirelessNetworkDataSource) Read(ctx context.Context, req datasource.Rea
return
}

networkResponse, _, err := d.client.ConfigurationAPI.
request := d.client.ConfigurationAPI.
GetConfigurationAppV1WirelessNetworksGet(context.Background()).
Uid(state.Filter.WirelessNetworkID).
Execute()
Uid(state.Filter.WirelessNetworkID)
networkResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(networkResponse.WirelessNetworks) != 1 {
resp.Diagnostics.AddError(
Expand Down
4 changes: 3 additions & 1 deletion pkg/config-api-provider/provider/resources/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand Down Expand Up @@ -103,7 +104,8 @@ func (r *groupResource) Create(ctx context.Context, req resource.CreateRequest,
}

groups_post_request := config_api_client.NewGroupsPostRequest(plan.ParentGroupId.ValueString(), plan.Name.ValueString())
group, _, err := r.client.ConfigurationAPI.GroupsPostConfigurationAppV1GroupsPost(context.Background()).GroupsPostRequest(*groups_post_request).Execute()
request := r.client.ConfigurationAPI.GroupsPostConfigurationAppV1GroupsPost(context.Background()).GroupsPostRequest(*groups_post_request)
group, _, err := util.RetryFor429(request.Execute)
if err != nil {
resp.Diagnostics.AddError(
"Error creating group",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
Expand Down Expand Up @@ -130,10 +131,10 @@ func (r *sensorGroupAssignmentResource) Read(ctx context.Context, req resource.R
return
}

sensorGroupAssignmentResponse, _, err := r.client.ConfigurationAPI.
request := r.client.ConfigurationAPI.
GetConfigurationAppV1SensorGroupAssignmentsGet(context.Background()).
Uid(state.ID.ValueString()).
Execute()
Uid(state.ID.ValueString())
sensorGroupAssignmentResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(sensorGroupAssignmentResponse.SensorGroupAssignments) != 1 {
resp.Diagnostics.AddError(
Expand Down
7 changes: 4 additions & 3 deletions pkg/config-api-provider/provider/resources/wired_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
Expand Down Expand Up @@ -88,10 +89,10 @@ func (r *wiredNetworkResource) Read(ctx context.Context, req resource.ReadReques
return
}

networkResponse, _, err := r.client.ConfigurationAPI.
request := r.client.ConfigurationAPI.
GetConfigurationAppV1WiredNetworksGet(context.Background()).
Uid(state.ID.ValueString()).
Execute()
Uid(state.ID.ValueString())
networkResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(networkResponse.WiredNetworks) != 1 {
resp.Diagnostics.AddError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
Expand Down Expand Up @@ -88,10 +89,10 @@ func (r *wirelessNetworkResource) Read(ctx context.Context, req resource.ReadReq
return
}

networkResponse, _, err := r.client.ConfigurationAPI.
request := r.client.ConfigurationAPI.
GetConfigurationAppV1WirelessNetworksGet(context.Background()).
Uid(state.ID.ValueString()).
Execute()
Uid(state.ID.ValueString())
networkResponse, _, err := util.RetryFor429(request.Execute)

if err != nil || len(networkResponse.WirelessNetworks) != 1 {
resp.Diagnostics.AddError(
Expand Down
34 changes: 34 additions & 0 deletions pkg/config-api-provider/provider/util/retry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package util

import (
"errors"
"net/http"
"strconv"
"time"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/config"
)

func RetryFor429[T any](f func() (T, *http.Response, error)) (T, *http.Response, error) {
var result T
var err error
var httpResponse *http.Response

for i := 0; i < config.MaxRetriesFor429; i++ {
result, httpResponse, err = f()

if httpResponse != nil && httpResponse.StatusCode != 429 {
return result, httpResponse, err
}

waitForSeconds := httpResponse.Header.Get("X-Ratelimit-Reset")
if waitForSeconds == "" {
return result, httpResponse, errors.Join(err, errors.New("header X-Ratelimit-Reset is missing or contains non valid value"))
}

rateLimitedFor, _ := strconv.Atoi(httpResponse.Header.Get("X-Ratelimit-Reset"))
time.Sleep(time.Duration(rateLimitedFor) * time.Second)
}

return result, httpResponse, errors.Join(err, errors.New("number of retries exceeded for 429 retries"))
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package test
package data_source

import (
"regexp"
"testing"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/provider"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/util"
"github.com/h2non/gock"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestGroupDataSource(t *testing.T) {
defer gock.Off()
MockOAuth()
mockOAuth := util.MockOAuth()

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Test no filters set
{
Config: providerConfig + `
Config: provider.ProviderConfig + `
data "uxi_group" "my_group" {
filter = {}
}
Expand All @@ -26,7 +28,7 @@ func TestGroupDataSource(t *testing.T) {
},
// Test too many filters set
{
Config: providerConfig + `
Config: provider.ProviderConfig + `
data "uxi_group" "my_group" {
filter = {
is_root = true
Expand All @@ -42,13 +44,13 @@ func TestGroupDataSource(t *testing.T) {
// Test Read, is_root not set
{
PreConfig: func() {
MockGetGroup(
util.MockGetGroup(
"uid",
GenerateGroupPaginatedResponse([]map[string]interface{}{StructToMap(GenerateGroupResponseModel("uid", "", ""))}),
util.GenerateGroupPaginatedResponse([]map[string]interface{}{util.StructToMap(util.GenerateGroupResponseModel("uid", "", ""))}),
3,
)
},
Config: providerConfig + `
Config: provider.ProviderConfig + `
data "uxi_group" "my_group" {
filter = {
group_id = "uid"
Expand All @@ -62,13 +64,13 @@ func TestGroupDataSource(t *testing.T) {
// Test Read, is_root is false
{
PreConfig: func() {
MockGetGroup(
util.MockGetGroup(
"uid",
GenerateGroupPaginatedResponse([]map[string]interface{}{StructToMap(GenerateGroupResponseModel("uid", "", ""))}),
util.GenerateGroupPaginatedResponse([]map[string]interface{}{util.StructToMap(util.GenerateGroupResponseModel("uid", "", ""))}),
3,
)
},
Config: providerConfig + `
Config: provider.ProviderConfig + `
data "uxi_group" "my_group" {
filter = {
is_root = false
Expand All @@ -83,4 +85,6 @@ func TestGroupDataSource(t *testing.T) {
// TODO: Test retrieving the root group
},
})

mockOAuth.Mock.Disable()
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package test
package data_source_test

import (
"testing"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/provider"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/util"
"github.com/h2non/gock"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"testing"
)

func TestSensorGroupAssignmentDataSource(t *testing.T) {
defer gock.Off()
MockOAuth()
mockOAuth := util.MockOAuth()

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Read testing
{
PreConfig: func() {
MockGetSensorGroupAssignment(
util.MockGetSensorGroupAssignment(
"uid",
GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{
StructToMap(GenerateSensorGroupAssignmentResponse("uid", "")),
util.GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{
util.StructToMap(util.GenerateSensorGroupAssignmentResponse("uid", "")),
}),
3,
)
},
Config: providerConfig + `
Config: provider.ProviderConfig + `
data "uxi_sensor_group_assignment" "my_sensor_group_assignment" {
filter = {
sensor_group_assignment_id = "uid"
Expand All @@ -40,4 +41,6 @@ func TestSensorGroupAssignmentDataSource(t *testing.T) {
},
},
})

mockOAuth.Mock.Disable()
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
package test
package data_source_test

import (
"testing"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/provider"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/util"

"github.com/h2non/gock"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestWiredNetworkDataSource(t *testing.T) {
defer gock.Off()
MockOAuth()
mockOAuth := util.MockOAuth()

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Read testing
{
PreConfig: func() {
MockGetWiredNetwork(
util.MockGetWiredNetwork(
"uid",
GenerateWiredNetworkPaginatedResponse([]map[string]interface{}{GenerateWiredNetworkResponse("uid", "")}),
util.GenerateWiredNetworkPaginatedResponse([]map[string]interface{}{util.GenerateWiredNetworkResponse("uid", "")}),
3,
)
},
Config: providerConfig + `
Config: provider.ProviderConfig + `
data "uxi_wired_network" "my_wired_network" {
filter = {
wired_network_id = "uid"
Expand All @@ -44,4 +47,6 @@ func TestWiredNetworkDataSource(t *testing.T) {
},
},
})

mockOAuth.Mock.Disable()
}
Loading

0 comments on commit 97a8d9c

Please sign in to comment.