Skip to content

Commit a24cbb8

Browse files
authored
Merge pull request #123 from authzed/add-linter
chore: add linter rules
2 parents b480ea8 + 964a16a commit a24cbb8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+204
-137
lines changed

.golangci.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
version: "2"
3+
run:
4+
allow-parallel-runners: true
5+
build-tags:
6+
- "mage"
7+
linters:
8+
enable:
9+
- "bidichk"
10+
# - "bodyclose"
11+
- "errcheck"
12+
- "errname"
13+
- "errorlint"
14+
- "gocritic"
15+
- "goprintffuncname"
16+
# - "gosec"
17+
- "govet"
18+
- "importas"
19+
- "ineffassign"
20+
- "makezero"
21+
- "prealloc"
22+
- "predeclared"
23+
- "promlinter"
24+
# - "revive"
25+
- "rowserrcheck"
26+
- "spancheck"
27+
- "staticcheck"
28+
- "tagalign"
29+
- "testifylint"
30+
- "tparallel"
31+
- "unconvert"
32+
# - "usetesting"
33+
- "wastedassign"
34+
- "whitespace"
35+
- "unused"
36+
settings:
37+
staticcheck:
38+
checks:
39+
- "all"
40+
- "-ST1000" # at least one file in a package should have a package comment
41+
- "-ST1003" # Poorly chosen identifier
42+
formatters:
43+
enable:
44+
- "gci"
45+
- "gofmt"
46+
- "gofumpt"
47+
- "goimports"
48+
settings:
49+
gofmt:
50+
rewrite-rules:
51+
- pattern: "interface{}"
52+
replacement: "any"
53+
gci:
54+
sections:
55+
- "standard"
56+
- "default"
57+
- "prefix(github.com/authzed)"
58+
- "localmodule"
59+
goimports:
60+
local-prefixes:
61+
- "github.com/authzed/terraform-provider-authzed"

internal/client/cloud_client.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ type ResponseWithETag struct {
118118
ETag string
119119
}
120120

121+
var _ HTTPResponder = (*ResponseWithETag)(nil)
122+
121123
// RequestOption allows setting optional parameters for requests
122124
type RequestOption func(*http.Request)
123125

@@ -273,13 +275,13 @@ func (c *CloudClient) waitForDeletion(endpoint string) error {
273275
}
274276
}
275277

276-
func backoffDelay(base, cap time.Duration, attempt int) time.Duration {
278+
func backoffDelay(base, capDelay time.Duration, attempt int) time.Duration {
277279
if attempt < 1 {
278280
attempt = 1
279281
}
280282
exp := time.Duration(float64(base) * math.Pow(2, float64(attempt-1)))
281-
if exp > cap {
282-
exp = cap
283+
if exp > capDelay {
284+
exp = capDelay
283285
}
284286
jitter := time.Duration(rand.Int63n(int64(exp) / 2))
285287
return exp + jitter
@@ -482,7 +484,7 @@ func (c *CloudClient) CreateResourceWithFactoryAndRecovery(ctx context.Context,
482484
if err != nil {
483485
// Attempt idempotent recovery for ambiguous outcomes
484486
if recovery != nil && isAmbiguousError(err) {
485-
if bodyMap, ok := body.(map[string]interface{}); ok {
487+
if bodyMap, ok := body.(map[string]any); ok {
486488
if name, exists := bodyMap["name"].(string); exists {
487489
if recovered, recErr := recovery.RecoverFromAmbiguousCreate(ctx, name, err); recErr == nil {
488490
return recovered, nil

internal/client/errors.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ type HTTPResponder interface {
1313
GetResponse() *http.Response
1414
}
1515

16-
// Make http.Response implement HTTPResponder
1716
type HTTPResponseWrapper struct {
1817
*http.Response
1918
}
@@ -22,7 +21,6 @@ func (r *HTTPResponseWrapper) GetResponse() *http.Response {
2221
return r.Response
2322
}
2423

25-
// Make ResponseWithETag implement HTTPResponder
2624
func (r *ResponseWithETag) GetResponse() *http.Response {
2725
return r.Response
2826
}

internal/client/permission_system.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (ps *PermissionsSystemWithETag) SetETag(etag string) {
3333
}
3434

3535
// GetResource returns the underlying permissions system
36-
func (ps *PermissionsSystemWithETag) GetResource() interface{} {
36+
func (ps *PermissionsSystemWithETag) GetResource() any {
3737
return ps.PermissionsSystem
3838
}
3939

internal/client/policy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (p *PolicyWithETag) SetETag(etag string) {
3333
}
3434

3535
// GetResource returns the underlying policy
36-
func (p *PolicyWithETag) GetResource() interface{} {
36+
func (p *PolicyWithETag) GetResource() any {
3737
return p.Policy
3838
}
3939

internal/client/retry.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"math"
78
"math/rand"
@@ -84,7 +85,7 @@ func (rc *RetryConfig) RetryWithExponentialBackoff(
8485
operationName, delay, attempt+1, rc.MaxRetries+1),
8586
)
8687

87-
tflog.Warn(ctx, "conflict detected, retrying with exponential backoff", map[string]interface{}{
88+
tflog.Warn(ctx, "conflict detected, retrying with exponential backoff", map[string]any{
8889
"operation": operationName,
8990
"status_code": resp.Response.StatusCode,
9091
"attempt": attempt + 1,
@@ -112,9 +113,10 @@ func (rc *RetryConfig) RetryWithExponentialBackoff(
112113
// If there's an error, check if it's retryable
113114
if lastErr != nil {
114115
// Check if this is a retryable error (APIError with retryable status code)
115-
if apiErr, ok := lastErr.(*APIError); ok && rc.ShouldRetry(apiErr.StatusCode) {
116+
apiErr := &APIError{}
117+
if errors.As(lastErr, &apiErr) && rc.ShouldRetry(apiErr.StatusCode) {
116118
// This is a retryable error, continue the retry loop
117-
tflog.Debug(ctx, "retryable error encountered, continuing retry loop", map[string]interface{}{
119+
tflog.Debug(ctx, "retryable error encountered, continuing retry loop", map[string]any{
118120
"operation": operationName,
119121
"status_code": apiErr.StatusCode,
120122
"attempt": attempt + 1,
@@ -138,7 +140,7 @@ func (rc *RetryConfig) RetryWithExponentialBackoff(
138140
operationName, attempt),
139141
)
140142

141-
tflog.Info(ctx, "retry succeeded", map[string]interface{}{
143+
tflog.Info(ctx, "retry succeeded", map[string]any{
142144
"operation": operationName,
143145
"final_attempt": attempt + 1,
144146
"total_retries": attempt,
@@ -162,7 +164,7 @@ func (rc *RetryConfig) RetryWithExponentialBackoff(
162164
rc.MaxRetries, operationName),
163165
)
164166

165-
tflog.Error(ctx, "retries exhausted", map[string]interface{}{
167+
tflog.Error(ctx, "retries exhausted", map[string]any{
166168
"operation": operationName,
167169
"max_attempts": rc.MaxRetries + 1,
168170
"final_status": resp.Response.StatusCode,
@@ -213,9 +215,10 @@ func (rc *RetryConfig) RetryWithExponentialBackoffLegacy(
213215
// If there's an error, check if it's retryable
214216
if lastErr != nil {
215217
// Check if this is a retryable error (APIError with retryable status code)
216-
if apiErr, ok := lastErr.(*APIError); ok && rc.ShouldRetry(apiErr.StatusCode) {
218+
apiErr := &APIError{}
219+
if errors.As(lastErr, &apiErr) && rc.ShouldRetry(apiErr.StatusCode) {
217220
// This is a retryable error, continue the retry loop
218-
tflog.Debug(ctx, "retryable error encountered, continuing retry loop", map[string]interface{}{
221+
tflog.Debug(ctx, "retryable error encountered, continuing retry loop", map[string]any{
219222
"operation": operationName,
220223
"status_code": apiErr.StatusCode,
221224
"attempt": attempt + 1,

internal/client/role.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7+
"errors"
78
"fmt"
89
"io"
910
"net/http"
@@ -34,7 +35,7 @@ func (r *RoleWithETag) SetETag(etag string) {
3435
}
3536

3637
// GetResource returns the underlying role
37-
func (r *RoleWithETag) GetResource() interface{} {
38+
func (r *RoleWithETag) GetResource() any {
3839
return r.Role
3940
}
4041

@@ -121,7 +122,8 @@ func (c *CloudClient) CreateRole(ctx context.Context, role *models.Role) (*RoleW
121122
resource, err := c.CreateResourceWithFactoryAndRecovery(ctx, path, role, &createdRole, NewRoleResource, recovery)
122123
if err != nil {
123124
// Special handling for specific errors
124-
if apiErr, ok := err.(*APIError); ok && apiErr.StatusCode == http.StatusInternalServerError {
125+
apiErr := &APIError{}
126+
if errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusInternalServerError {
125127
// Check if the error message indicates a duplicate name
126128
if strings.Contains(string(apiErr.Body), "duplicate") || strings.Contains(string(apiErr.Body), "already exists") {
127129
return nil, fmt.Errorf("role with name '%s' already exists in permission system '%s'", role.Name, role.PermissionsSystemID)

internal/client/service_account.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66
"fmt"
77
"io"
88
"net/http"
9-
"terraform-provider-authzed/internal/models"
109

1110
"github.com/hashicorp/terraform-plugin-framework/diag"
11+
12+
"terraform-provider-authzed/internal/models"
1213
)
1314

1415
// ServiceAccountWithETag represents a service account resource with its ETag
@@ -33,7 +34,7 @@ func (sa *ServiceAccountWithETag) SetETag(etag string) {
3334
}
3435

3536
// GetResource returns the underlying service account
36-
func (sa *ServiceAccountWithETag) GetResource() interface{} {
37+
func (sa *ServiceAccountWithETag) GetResource() any {
3738
return sa.ServiceAccount
3839
}
3940

internal/client/test/etag_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import (
66
"net/http/httptest"
77
"testing"
88

9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
912
"terraform-provider-authzed/internal/client"
1013
"terraform-provider-authzed/internal/models"
11-
12-
"github.com/stretchr/testify/assert"
1314
)
1415

1516
func TestETagSupport(t *testing.T) {
@@ -113,7 +114,7 @@ func TestETagSupport(t *testing.T) {
113114
getRequestCount = 0
114115

115116
sa, err := c.GetServiceAccount(context.Background(), "ps-test123", "asa-test123")
116-
assert.NoError(t, err)
117+
require.NoError(t, err)
117118
assert.Equal(t, testETag, sa.GetETag())
118119
})
119120

internal/client/test/fgam_error_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package test
33
import (
44
"testing"
55

6-
"terraform-provider-authzed/internal/client"
7-
86
"github.com/stretchr/testify/assert"
7+
8+
"terraform-provider-authzed/internal/client"
99
)
1010

1111
func TestFGAMErrorMessages(t *testing.T) {

0 commit comments

Comments
 (0)