Skip to content

Commit 1c08cb2

Browse files
Merge pull request #42 from 86254860/HYPERFLEET-455
Hyperfleet-455 - fix: use standard .golangci.yml and fix lint issues
2 parents ef43dfc + 58c1a89 commit 1c08cb2

63 files changed

Lines changed: 924 additions & 347 deletions

Some content is hidden

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

.golangci.yml

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,108 @@
1-
version: 2
1+
# HyperFleet Standard golangci-lint Configuration
2+
# Reference: https://golangci-lint.run/usage/configuration
3+
#
4+
# This is the baseline configuration for all HyperFleet Go repositories.
5+
# Copy this file to your repository root as .golangci.yml
6+
#
7+
# golangci-lint should be installed and versioned via bingo in each repository.
8+
# See linting.md for full documentation of this standard.
9+
10+
version: "2"
11+
12+
run:
13+
timeout: 5m
14+
tests: true
15+
modules-download-mode: readonly
16+
17+
linters-settings:
18+
errcheck:
19+
check-type-assertions: true
20+
check-blank: true
21+
22+
govet:
23+
enable-all: true
24+
25+
goconst:
26+
min-len: 3
27+
min-occurrences: 3
28+
29+
misspell:
30+
locale: US
31+
32+
lll:
33+
line-length: 120
34+
35+
gofmt:
36+
simplify: true
37+
38+
revive:
39+
rules:
40+
- name: exported
41+
severity: warning
42+
disabled: true
43+
- name: unexported-return
44+
severity: warning
45+
disabled: false
46+
- name: var-naming
47+
severity: warning
48+
disabled: false
49+
50+
unused:
51+
check-exported: false
52+
53+
unparam:
54+
check-exported: false
55+
56+
exhaustive:
57+
check-generated: false
58+
default-signifies-exhaustive: true
59+
60+
linters:
61+
enable:
62+
# Code Quality
63+
- errcheck
64+
- govet
65+
- staticcheck
66+
- ineffassign
67+
- unused
68+
- unconvert
69+
- unparam
70+
- goconst
71+
- exhaustive
72+
73+
# Code Style
74+
- misspell
75+
- lll
76+
# - revive
77+
- gocritic
78+
79+
# Security
80+
- gosec
81+
282
issues:
83+
# Add repository-specific generated code directories here
384
exclude-dirs:
485
- pkg/api/openapi # Generated code
586
- data/generated/openapi # Generated file
87+
88+
exclude-rules:
89+
# Relaxed rules for test files
90+
- path: _test\.go
91+
linters:
92+
- gosec
93+
- errcheck
94+
- unparam
95+
96+
# Exclude generated code (backup pattern if exclude-dirs doesn't catch all)
97+
- path: pkg/api/openapi/
98+
linters:
99+
- all
100+
101+
max-issues-per-linter: 0
102+
max-same-issues: 0
103+
new: false
104+
105+
output:
106+
format: colored-line-number
107+
print-issued-lines: true
108+
print-linter-name: true

cmd/hyperfleet-api/servecmd/cmd.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ func runServe(cmd *cobra.Command, args []string) {
113113
}
114114

115115
if tp != nil {
116-
shutdownCtx, cancel := context.WithTimeout(context.Background(), environments.Environment().Config.Health.ShutdownTimeout)
116+
shutdownCtx, cancel := context.WithTimeout(
117+
context.Background(), environments.Environment().Config.Health.ShutdownTimeout,
118+
)
117119
defer cancel()
118120
if err := telemetry.Shutdown(shutdownCtx, tp); err != nil {
119121
logger.WithError(ctx, err).Error("Failed to shutdown OpenTelemetry")

cmd/hyperfleet-api/server/api_server.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ func NewAPIServer() Server {
9393
mainHandler = removeTrailingSlash(mainHandler)
9494

9595
s.httpServer = &http.Server{
96-
Addr: env().Config.Server.BindAddress,
97-
Handler: mainHandler,
96+
Addr: env().Config.Server.BindAddress,
97+
Handler: mainHandler,
98+
ReadHeaderTimeout: 10 * time.Second,
9899
}
99100

100101
return s
@@ -136,7 +137,8 @@ func (s apiServer) Listen() (listener net.Listener, err error) {
136137
return net.Listen("tcp", env().Config.Server.BindAddress)
137138
}
138139

139-
// Start listening on the configured port and start the server. This is a convenience wrapper for Listen() and Serve(listener Listener)
140+
// Start listening on the configured port and start the server.
141+
// This is a convenience wrapper for Listen() and Serve(listener Listener)
140142
func (s apiServer) Start() {
141143
ctx := context.Background()
142144
listener, err := s.Listen()

cmd/hyperfleet-api/server/health_server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ func NewHealthServer() Server {
3030
listening: make(chan struct{}),
3131
}
3232
s.httpServer = &http.Server{
33-
Addr: env().Config.Health.BindAddress,
34-
Handler: mainHandler,
33+
Addr: env().Config.Health.BindAddress,
34+
Handler: mainHandler,
35+
ReadHeaderTimeout: 10 * time.Second,
3536
}
3637
return s
3738
}

cmd/hyperfleet-api/server/metrics_server.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net"
77
"net/http"
8+
"time"
89

910
"github.com/gorilla/mux"
1011

@@ -25,8 +26,9 @@ func NewMetricsServer() Server {
2526

2627
s := &metricsServer{}
2728
s.httpServer = &http.Server{
28-
Addr: env().Config.Metrics.BindAddress,
29-
Handler: mainHandler,
29+
Addr: env().Config.Metrics.BindAddress,
30+
Handler: mainHandler,
31+
ReadHeaderTimeout: 10 * time.Second,
3032
}
3133
return s
3234
}

cmd/hyperfleet-api/server/routes.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,25 @@ type ServicesInterface interface {
2323
GetService(name string) interface{}
2424
}
2525

26-
type RouteRegistrationFunc func(apiV1Router *mux.Router, services ServicesInterface, authMiddleware auth.JWTMiddleware, authzMiddleware auth.AuthorizationMiddleware)
26+
type RouteRegistrationFunc func(
27+
apiV1Router *mux.Router,
28+
services ServicesInterface,
29+
authMiddleware auth.JWTMiddleware,
30+
authzMiddleware auth.AuthorizationMiddleware,
31+
)
2732

2833
var routeRegistry = make(map[string]RouteRegistrationFunc)
2934

3035
func RegisterRoutes(name string, registrationFunc RouteRegistrationFunc) {
3136
routeRegistry[name] = registrationFunc
3237
}
3338

34-
func LoadDiscoveredRoutes(apiV1Router *mux.Router, services ServicesInterface, authMiddleware auth.JWTMiddleware, authzMiddleware auth.AuthorizationMiddleware) {
39+
func LoadDiscoveredRoutes(
40+
apiV1Router *mux.Router,
41+
services ServicesInterface,
42+
authMiddleware auth.JWTMiddleware,
43+
authzMiddleware auth.AuthorizationMiddleware,
44+
) {
3545
for name, registrationFunc := range routeRegistry {
3646
registrationFunc(apiV1Router, services, authMiddleware, authzMiddleware)
3747
_ = name // prevent unused variable warning

pkg/api/presenters/cluster_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import (
1212
"github.com/openshift-hyperfleet/hyperfleet-api/pkg/util"
1313
)
1414

15+
const (
16+
testConditionReady = "Ready"
17+
)
18+
1519
// Helper function to create test ClusterCreateRequest
1620
func createTestClusterRequest() *openapi.ClusterCreateRequest {
1721
labels := map[string]string{"env": "test"}
@@ -157,7 +161,7 @@ func TestPresentCluster_Complete(t *testing.T) {
157161
RegisterTestingT(t)
158162

159163
now := time.Now()
160-
reason := "Ready"
164+
reason := testConditionReady
161165
message := "Cluster is ready"
162166

163167
// Create domain ResourceCondition
@@ -218,7 +222,7 @@ func TestPresentCluster_Complete(t *testing.T) {
218222
Expect(len(result.Status.Conditions)).To(Equal(1))
219223
Expect(result.Status.Conditions[0].Type).To(Equal("Available"))
220224
Expect(result.Status.Conditions[0].Status).To(Equal(openapi.ResourceConditionStatusTrue))
221-
Expect(*result.Status.Conditions[0].Reason).To(Equal("Ready"))
225+
Expect(*result.Status.Conditions[0].Reason).To(Equal(testConditionReady))
222226

223227
// Verify timestamps
224228
Expect(result.CreatedTime.Unix()).To(Equal(now.Unix()))
@@ -300,7 +304,7 @@ func TestPresentCluster_StatusConditionsConversion(t *testing.T) {
300304
// First condition
301305
Expect(result.Status.Conditions[0].Type).To(Equal("Available"))
302306
Expect(result.Status.Conditions[0].Status).To(Equal(openapi.ResourceConditionStatusTrue))
303-
Expect(*result.Status.Conditions[0].Reason).To(Equal("Ready"))
307+
Expect(*result.Status.Conditions[0].Reason).To(Equal(testConditionReady))
304308
Expect(*result.Status.Conditions[0].Message).To(Equal("All systems operational"))
305309

306310
// Second condition

pkg/api/presenters/slice_filter.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ func validate(model interface{}, in map[string]bool, prefix string) *errors.Serv
103103
}
104104
field := reflectValue.Field(i).Interface()
105105
name := strings.Split(tag, ",")[0]
106-
if kind == reflect.Struct {
106+
switch kind { //nolint:exhaustive // Only Struct and Slice need special handling, rest handled by default
107+
case reflect.Struct:
107108
if t.Type == reflect.TypeOf(&time.Time{}) {
108109
delete(in, name)
109110
} else {
@@ -116,12 +117,12 @@ func validate(model interface{}, in map[string]bool, prefix string) *errors.Serv
116117
}
117118
}
118119
}
119-
} else if t.Type.Kind() == reflect.Slice {
120+
case reflect.Slice:
120121
// TODO: We don't support Slices' validation :(
121122
in = removeStar(in, name)
122123
continue
123-
//_ = validate(slice, in, name)
124-
} else {
124+
// _ = validate(slice, in, name)
125+
default:
125126
prefixedName := name
126127
if prefix != "" {
127128
prefixedName = fmt.Sprintf("%s.%s", prefix, name)
@@ -188,7 +189,8 @@ func structToMap(item interface{}, in map[string]bool, prefix string) map[string
188189
}
189190
field := reflectValue.Field(i).Interface()
190191
name := strings.Split(tag, ",")[0]
191-
if kind == reflect.Struct {
192+
switch kind { //nolint:exhaustive // Only Struct and Slice need special handling, rest handled by default
193+
case reflect.Struct:
192194
if t.Type == reflect.TypeOf(&time.Time{}) {
193195
if _, ok := in[name]; ok {
194196
if timePtr, ok := field.(*time.Time); ok && timePtr != nil {
@@ -205,7 +207,7 @@ func structToMap(item interface{}, in map[string]bool, prefix string) map[string
205207
res[name] = subStruct
206208
}
207209
}
208-
} else if kind == reflect.Slice {
210+
case reflect.Slice:
209211
s := reflect.ValueOf(field)
210212
if s.Len() > 0 {
211213
result := make([]interface{}, 0, s.Len())
@@ -220,7 +222,7 @@ func structToMap(item interface{}, in map[string]bool, prefix string) map[string
220222
res[name] = result
221223
}
222224
}
223-
} else {
225+
default:
224226
prefixedName := name
225227
if prefix != "" {
226228
prefixedName = fmt.Sprintf("%s.%s", prefix, name)

pkg/auth/auth_middleware.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ func (a *Middleware) AuthenticateAccountJWT(next http.Handler) http.Handler {
2626
ctx := r.Context()
2727
payload, err := GetAuthPayload(r)
2828
if err != nil {
29-
handleError(ctx, w, r, errors.CodeAuthNoCredentials, fmt.Sprintf("Unable to get payload details from JWT token: %s", err))
29+
handleError(
30+
ctx, w, r, errors.CodeAuthNoCredentials,
31+
fmt.Sprintf("Unable to get payload details from JWT token: %s", err),
32+
)
3033
return
3134
}
3235

pkg/auth/authz_middleware.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ func (a authzMiddleware) AuthorizeApi(next http.Handler) http.Handler {
4646
if username == "" {
4747
_ = fmt.Errorf("authenticated username not present in request context")
4848
// TODO
49-
//body := api.E500.Format(r, "Authentication details not present in context")
50-
//api.SendError(w, r, &body)
49+
// body := api.E500.Format(r, "Authentication details not present in context")
50+
// api.SendError(w, r, &body)
5151
return
5252
}
5353

@@ -56,8 +56,8 @@ func (a authzMiddleware) AuthorizeApi(next http.Handler) http.Handler {
5656
if err != nil {
5757
_ = fmt.Errorf("unable to make authorization request: %s", err)
5858
// TODO
59-
//body := api.E500.Format(r, "Unable to make authorization request")
60-
//api.SendError(w, r, &body)
59+
// body := api.E500.Format(r, "Unable to make authorization request")
60+
// api.SendError(w, r, &body)
6161
return
6262
}
6363

@@ -66,7 +66,7 @@ func (a authzMiddleware) AuthorizeApi(next http.Handler) http.Handler {
6666
}
6767

6868
// TODO
69-
//body := api.E403.Format(r, "")
70-
//api.SendError(w, r, &body)
69+
// body := api.E403.Format(r, "")
70+
// api.SendError(w, r, &body)
7171
})
7272
}

0 commit comments

Comments
 (0)