Skip to content

Commit c1ab204

Browse files
committed
fix(lint): resolve golangci-lint errors found during QA verification
- Fix errcheck errors in pkg/controller/storage.go for unmarshalJSON calls - Fix ineffassign in pkg/exporters/http/report.go - Fix ineffassign in test/integration/config/config_reload_test.go - Add nolint directive for gosec G404 in pinger.go (ping ID doesn't need crypto/rand) - Run gofmt on multiple files to fix formatting issues QA Verification Status: - Build: PASSED - Lint: PASSED - Tests: ALL PASSING (unit + integration) - QA Agent Review: PASSED (all 5 phases verified) - Devils Advocate: PASSED (implementation confirmed legitimate)
1 parent 108a8ad commit c1ab204

File tree

13 files changed

+157
-165
lines changed

13 files changed

+157
-165
lines changed

pkg/controller/events.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,27 @@ import (
1818
// Event reasons for different scenarios
1919
const (
2020
// Cluster health events
21-
EventReasonClusterDegraded = "ClusterDegraded"
22-
EventReasonClusterCritical = "ClusterCritical"
23-
EventReasonClusterRecovered = "ClusterRecovered"
24-
EventReasonNodeHealthChanged = "NodeHealthChanged"
21+
EventReasonClusterDegraded = "ClusterDegraded"
22+
EventReasonClusterCritical = "ClusterCritical"
23+
EventReasonClusterRecovered = "ClusterRecovered"
24+
EventReasonNodeHealthChanged = "NodeHealthChanged"
2525

2626
// Problem events
27-
EventReasonProblemDetected = "ProblemDetected"
28-
EventReasonProblemResolved = "ProblemResolved"
29-
EventReasonClusterWideProblem = "ClusterWideProblem"
27+
EventReasonProblemDetected = "ProblemDetected"
28+
EventReasonProblemResolved = "ProblemResolved"
29+
EventReasonClusterWideProblem = "ClusterWideProblem"
3030

3131
// Correlation events
32-
EventReasonCorrelationDetected = "CorrelationDetected"
33-
EventReasonCorrelationResolved = "CorrelationResolved"
32+
EventReasonCorrelationDetected = "CorrelationDetected"
33+
EventReasonCorrelationResolved = "CorrelationResolved"
3434

3535
// Remediation events
36-
EventReasonLeaseGranted = "RemediationLeaseGranted"
37-
EventReasonLeaseDenied = "RemediationLeaseDenied"
38-
EventReasonLeaseExpired = "RemediationLeaseExpired"
39-
EventReasonRemediationStarted = "RemediationStarted"
40-
EventReasonRemediationCompleted = "RemediationCompleted"
41-
EventReasonRemediationFailed = "RemediationFailed"
36+
EventReasonLeaseGranted = "RemediationLeaseGranted"
37+
EventReasonLeaseDenied = "RemediationLeaseDenied"
38+
EventReasonLeaseExpired = "RemediationLeaseExpired"
39+
EventReasonRemediationStarted = "RemediationStarted"
40+
EventReasonRemediationCompleted = "RemediationCompleted"
41+
EventReasonRemediationFailed = "RemediationFailed"
4242
)
4343

4444
// Event types
@@ -49,16 +49,16 @@ const (
4949

5050
// EventRecorder creates Kubernetes Events for cluster-level issues
5151
type EventRecorder struct {
52-
client kubernetes.Interface
53-
namespace string
54-
enabled bool
55-
controllerName string
56-
componentName string
52+
client kubernetes.Interface
53+
namespace string
54+
enabled bool
55+
controllerName string
56+
componentName string
5757

5858
// Rate limiting to prevent event spam
59-
mu sync.RWMutex
60-
lastEventTime map[string]time.Time
61-
rateLimitPeriod time.Duration
59+
mu sync.RWMutex
60+
lastEventTime map[string]time.Time
61+
rateLimitPeriod time.Duration
6262
}
6363

6464
// EventRecorderConfig holds configuration for the EventRecorder

pkg/controller/events_test.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import (
1111

1212
func TestNewEventRecorder(t *testing.T) {
1313
tests := []struct {
14-
name string
15-
config *EventRecorderConfig
16-
wantErr bool
17-
wantNil bool
14+
name string
15+
config *EventRecorderConfig
16+
wantErr bool
17+
wantNil bool
1818
wantEnabled bool
1919
}{
2020
{
@@ -159,19 +159,19 @@ func TestEventRecorder_RecordClusterHealthChange(t *testing.T) {
159159
ctx := context.Background()
160160

161161
tests := []struct {
162-
name string
163-
status *ClusterStatus
164-
previousHealth HealthStatus
165-
expectEvent bool
166-
expectedReason string
162+
name string
163+
status *ClusterStatus
164+
previousHealth HealthStatus
165+
expectEvent bool
166+
expectedReason string
167167
}{
168168
{
169169
name: "critical cluster creates event",
170170
status: &ClusterStatus{
171-
OverallHealth: HealthStatusCritical,
172-
TotalNodes: 10,
173-
CriticalNodes: 3,
174-
DegradedNodes: 2,
171+
OverallHealth: HealthStatusCritical,
172+
TotalNodes: 10,
173+
CriticalNodes: 3,
174+
DegradedNodes: 2,
175175
},
176176
previousHealth: HealthStatusDegraded,
177177
expectEvent: true,
@@ -180,10 +180,10 @@ func TestEventRecorder_RecordClusterHealthChange(t *testing.T) {
180180
{
181181
name: "degraded cluster creates event",
182182
status: &ClusterStatus{
183-
OverallHealth: HealthStatusDegraded,
184-
TotalNodes: 10,
185-
DegradedNodes: 3,
186-
HealthyNodes: 7,
183+
OverallHealth: HealthStatusDegraded,
184+
TotalNodes: 10,
185+
DegradedNodes: 3,
186+
HealthyNodes: 7,
187187
},
188188
previousHealth: HealthStatusHealthy,
189189
expectEvent: true,
@@ -192,9 +192,9 @@ func TestEventRecorder_RecordClusterHealthChange(t *testing.T) {
192192
{
193193
name: "recovery creates event",
194194
status: &ClusterStatus{
195-
OverallHealth: HealthStatusHealthy,
196-
TotalNodes: 10,
197-
HealthyNodes: 10,
195+
OverallHealth: HealthStatusHealthy,
196+
TotalNodes: 10,
197+
HealthyNodes: 10,
198198
},
199199
previousHealth: HealthStatusCritical,
200200
expectEvent: true,
@@ -203,9 +203,9 @@ func TestEventRecorder_RecordClusterHealthChange(t *testing.T) {
203203
{
204204
name: "healthy to healthy no event",
205205
status: &ClusterStatus{
206-
OverallHealth: HealthStatusHealthy,
207-
TotalNodes: 10,
208-
HealthyNodes: 10,
206+
OverallHealth: HealthStatusHealthy,
207+
TotalNodes: 10,
208+
HealthyNodes: 10,
209209
},
210210
previousHealth: HealthStatusHealthy,
211211
expectEvent: false,

pkg/controller/storage.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,15 @@ func (s *SQLiteStorage) GetCorrelation(ctx context.Context, id string) (*Correla
526526
return nil, fmt.Errorf("failed to get correlation: %w", err)
527527
}
528528

529-
unmarshalJSON(affectedNodes, &correlation.AffectedNodes)
530-
unmarshalJSON(problemTypes, &correlation.ProblemTypes)
531-
unmarshalJSON(metadata, &correlation.Metadata)
529+
if err := unmarshalJSON(affectedNodes, &correlation.AffectedNodes); err != nil {
530+
return nil, fmt.Errorf("failed to unmarshal affected nodes: %w", err)
531+
}
532+
if err := unmarshalJSON(problemTypes, &correlation.ProblemTypes); err != nil {
533+
return nil, fmt.Errorf("failed to unmarshal problem types: %w", err)
534+
}
535+
if err := unmarshalJSON(metadata, &correlation.Metadata); err != nil {
536+
return nil, fmt.Errorf("failed to unmarshal metadata: %w", err)
537+
}
532538

533539
return &correlation, nil
534540
}
@@ -560,9 +566,15 @@ func (s *SQLiteStorage) GetActiveCorrelations(ctx context.Context) ([]*Correlati
560566
return nil, fmt.Errorf("failed to scan correlation: %w", err)
561567
}
562568

563-
unmarshalJSON(affectedNodes, &correlation.AffectedNodes)
564-
unmarshalJSON(problemTypes, &correlation.ProblemTypes)
565-
unmarshalJSON(metadata, &correlation.Metadata)
569+
if err := unmarshalJSON(affectedNodes, &correlation.AffectedNodes); err != nil {
570+
return nil, fmt.Errorf("failed to unmarshal affected nodes: %w", err)
571+
}
572+
if err := unmarshalJSON(problemTypes, &correlation.ProblemTypes); err != nil {
573+
return nil, fmt.Errorf("failed to unmarshal problem types: %w", err)
574+
}
575+
if err := unmarshalJSON(metadata, &correlation.Metadata); err != nil {
576+
return nil, fmt.Errorf("failed to unmarshal metadata: %w", err)
577+
}
566578

567579
correlations = append(correlations, &correlation)
568580
}

pkg/controller/storage_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ func TestSQLiteStorage_Correlations(t *testing.T) {
406406
Severity: "critical", // Updated severity
407407
Status: "active",
408408
Message: "Multiple nodes experiencing DNS issues",
409-
Confidence: 0.95, // Updated confidence
409+
Confidence: 0.95, // Updated confidence
410410
AffectedNodes: []string{"node-1", "node-2", "node-3", "node-4"}, // Added node
411411
DetectedAt: time.Now(),
412412
UpdatedAt: time.Now(),

pkg/controller/types.go

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -96,38 +96,38 @@ type NodeStats struct {
9696

9797
// ClusterStatus represents the overall cluster health status
9898
type ClusterStatus struct {
99-
Timestamp time.Time `json:"timestamp"`
100-
OverallHealth HealthStatus `json:"overallHealth"`
101-
TotalNodes int `json:"totalNodes"`
102-
HealthyNodes int `json:"healthyNodes"`
103-
DegradedNodes int `json:"degradedNodes"`
104-
CriticalNodes int `json:"criticalNodes"`
105-
UnknownNodes int `json:"unknownNodes"`
106-
ActiveProblems int `json:"activeProblems"`
107-
Correlations int `json:"activeCorrelations"`
108-
NodeSummaries []NodeSummary `json:"nodeSummaries,omitempty"`
109-
RecentProblems []ClusterProblem `json:"recentProblems,omitempty"`
99+
Timestamp time.Time `json:"timestamp"`
100+
OverallHealth HealthStatus `json:"overallHealth"`
101+
TotalNodes int `json:"totalNodes"`
102+
HealthyNodes int `json:"healthyNodes"`
103+
DegradedNodes int `json:"degradedNodes"`
104+
CriticalNodes int `json:"criticalNodes"`
105+
UnknownNodes int `json:"unknownNodes"`
106+
ActiveProblems int `json:"activeProblems"`
107+
Correlations int `json:"activeCorrelations"`
108+
NodeSummaries []NodeSummary `json:"nodeSummaries,omitempty"`
109+
RecentProblems []ClusterProblem `json:"recentProblems,omitempty"`
110110
}
111111

112112
// NodeSummary provides a brief overview of a node's status
113113
type NodeSummary struct {
114-
NodeName string `json:"nodeName"`
115-
Health HealthStatus `json:"health"`
116-
LastReportAt time.Time `json:"lastReportAt"`
117-
ProblemCount int `json:"problemCount"`
118-
ConditionCount int `json:"conditionCount"`
114+
NodeName string `json:"nodeName"`
115+
Health HealthStatus `json:"health"`
116+
LastReportAt time.Time `json:"lastReportAt"`
117+
ProblemCount int `json:"problemCount"`
118+
ConditionCount int `json:"conditionCount"`
119119
}
120120

121121
// ClusterProblem represents a problem affecting the cluster
122122
type ClusterProblem struct {
123-
ID string `json:"id"`
124-
Type string `json:"type"`
125-
Severity string `json:"severity"`
126-
AffectedNodes []string `json:"affectedNodes"`
127-
Message string `json:"message"`
128-
DetectedAt time.Time `json:"detectedAt"`
129-
IsCorrelated bool `json:"isCorrelated"`
130-
CorrelationID string `json:"correlationId,omitempty"`
123+
ID string `json:"id"`
124+
Type string `json:"type"`
125+
Severity string `json:"severity"`
126+
AffectedNodes []string `json:"affectedNodes"`
127+
Message string `json:"message"`
128+
DetectedAt time.Time `json:"detectedAt"`
129+
IsCorrelated bool `json:"isCorrelated"`
130+
CorrelationID string `json:"correlationId,omitempty"`
131131
}
132132

133133
// =====================
@@ -162,16 +162,16 @@ type ReportSummary struct {
162162

163163
// Correlation represents a detected pattern across multiple nodes
164164
type Correlation struct {
165-
ID string `json:"id"`
166-
Type string `json:"type"` // infrastructure, common-cause, cascade
167-
Severity string `json:"severity"`
168-
AffectedNodes []string `json:"affectedNodes"`
169-
ProblemTypes []string `json:"problemTypes"`
170-
Message string `json:"message"`
171-
DetectedAt time.Time `json:"detectedAt"`
172-
UpdatedAt time.Time `json:"updatedAt"`
173-
Status string `json:"status"` // active, resolved, investigating
174-
Confidence float64 `json:"confidence"`
165+
ID string `json:"id"`
166+
Type string `json:"type"` // infrastructure, common-cause, cascade
167+
Severity string `json:"severity"`
168+
AffectedNodes []string `json:"affectedNodes"`
169+
ProblemTypes []string `json:"problemTypes"`
170+
Message string `json:"message"`
171+
DetectedAt time.Time `json:"detectedAt"`
172+
UpdatedAt time.Time `json:"updatedAt"`
173+
Status string `json:"status"` // active, resolved, investigating
174+
Confidence float64 `json:"confidence"`
175175
Metadata map[string]interface{} `json:"metadata,omitempty"`
176176
}
177177

@@ -194,7 +194,7 @@ type LeaseResponse struct {
194194
Approved bool `json:"approved"`
195195
ExpiresAt time.Time `json:"expiresAt,omitempty"`
196196
Message string `json:"message,omitempty"`
197-
RetryAt time.Time `json:"retryAt,omitempty"` // when to retry if denied
197+
RetryAt time.Time `json:"retryAt,omitempty"` // when to retry if denied
198198
Position int `json:"position,omitempty"` // queue position if waiting
199199
}
200200

@@ -279,34 +279,34 @@ type StorageConfig struct {
279279

280280
// CorrelationConfig contains correlation engine settings
281281
type CorrelationConfig struct {
282-
Enabled bool `json:"enabled" yaml:"enabled"`
283-
ClusterWideThreshold float64 `json:"clusterWideThreshold" yaml:"clusterWideThreshold"`
284-
EvaluationInterval time.Duration `json:"evaluationInterval" yaml:"evaluationInterval"`
285-
MinNodesForCorrelation int `json:"minNodesForCorrelation" yaml:"minNodesForCorrelation"`
282+
Enabled bool `json:"enabled" yaml:"enabled"`
283+
ClusterWideThreshold float64 `json:"clusterWideThreshold" yaml:"clusterWideThreshold"`
284+
EvaluationInterval time.Duration `json:"evaluationInterval" yaml:"evaluationInterval"`
285+
MinNodesForCorrelation int `json:"minNodesForCorrelation" yaml:"minNodesForCorrelation"`
286286
}
287287

288288
// CoordinationConfig contains remediation coordination settings
289289
type CoordinationConfig struct {
290-
Enabled bool `json:"enabled" yaml:"enabled"`
291-
MaxConcurrentRemediations int `json:"maxConcurrentRemediations" yaml:"maxConcurrentRemediations"`
292-
DefaultLeaseDuration time.Duration `json:"defaultLeaseDuration" yaml:"defaultLeaseDuration"`
293-
CooldownPeriod time.Duration `json:"cooldownPeriod" yaml:"cooldownPeriod"`
290+
Enabled bool `json:"enabled" yaml:"enabled"`
291+
MaxConcurrentRemediations int `json:"maxConcurrentRemediations" yaml:"maxConcurrentRemediations"`
292+
DefaultLeaseDuration time.Duration `json:"defaultLeaseDuration" yaml:"defaultLeaseDuration"`
293+
CooldownPeriod time.Duration `json:"cooldownPeriod" yaml:"cooldownPeriod"`
294294
}
295295

296296
// PrometheusConfig contains Prometheus metrics configuration
297297
type PrometheusConfig struct {
298-
Enabled bool `json:"enabled" yaml:"enabled"`
299-
Port int `json:"port" yaml:"port"`
298+
Enabled bool `json:"enabled" yaml:"enabled"`
299+
Port int `json:"port" yaml:"port"`
300300
Path string `json:"path" yaml:"path"`
301301
}
302302

303303
// KubernetesConfig contains Kubernetes integration settings
304304
type KubernetesConfig struct {
305-
Enabled bool `json:"enabled" yaml:"enabled"`
306-
Kubeconfig string `json:"kubeconfig" yaml:"kubeconfig"`
307-
InCluster bool `json:"inCluster" yaml:"inCluster"`
308-
Namespace string `json:"namespace" yaml:"namespace"`
309-
CreateEvents bool `json:"createEvents" yaml:"createEvents"`
305+
Enabled bool `json:"enabled" yaml:"enabled"`
306+
Kubeconfig string `json:"kubeconfig" yaml:"kubeconfig"`
307+
InCluster bool `json:"inCluster" yaml:"inCluster"`
308+
Namespace string `json:"namespace" yaml:"namespace"`
309+
CreateEvents bool `json:"createEvents" yaml:"createEvents"`
310310
}
311311

312312
// DefaultControllerConfig returns a configuration with sensible defaults
@@ -324,10 +324,10 @@ func DefaultControllerConfig() *ControllerConfig {
324324
Retention: 30 * 24 * time.Hour, // 30 days
325325
},
326326
Correlation: CorrelationConfig{
327-
Enabled: true,
328-
ClusterWideThreshold: 0.3, // 30% of nodes
329-
EvaluationInterval: 30 * time.Second,
330-
MinNodesForCorrelation: 2,
327+
Enabled: true,
328+
ClusterWideThreshold: 0.3, // 30% of nodes
329+
EvaluationInterval: 30 * time.Second,
330+
MinNodesForCorrelation: 2,
331331
},
332332
Coordination: CoordinationConfig{
333333
Enabled: true,

pkg/exporters/http/report.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func (rb *ReportBuilder) convertMonitorStatus(status *types.Status) *controller.
240240
// convertCondition converts a types.Condition to a controller.NodeCondition.
241241
func (rb *ReportBuilder) convertCondition(cond types.Condition) *controller.NodeCondition {
242242
// Convert condition status to string
243-
statusStr := "Unknown"
243+
var statusStr string
244244
switch cond.Status {
245245
case types.ConditionTrue:
246246
statusStr = "True"

pkg/exporters/kubernetes/condition_manager.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -535,10 +535,10 @@ func (cm *ConditionManager) ClearManagedConditions() []string {
535535

536536
// Conditions managed by node-doctor (common patterns)
537537
nodeDoctorConditionPrefixes := []string{
538-
"NodeDoctor", // e.g., NodeDoctorHealthy, NodeDoctorCPU
539-
"CPUPressure", // system-cpu monitor
540-
"MemoryPressure", // system-memory monitor (may conflict with k8s built-in)
541-
"DiskPressure", // system-disk monitor (may conflict with k8s built-in)
538+
"NodeDoctor", // e.g., NodeDoctorHealthy, NodeDoctorCPU
539+
"CPUPressure", // system-cpu monitor
540+
"MemoryPressure", // system-memory monitor (may conflict with k8s built-in)
541+
"DiskPressure", // system-disk monitor (may conflict with k8s built-in)
542542
"NetworkUnreachable",
543543
"DNSResolutionFailed",
544544
"GatewayUnreachable",

pkg/monitors/network/cni.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ type CNIMonitor struct {
111111
started bool
112112

113113
// State tracking for delta-based event emission (issue #8)
114-
lastHighLatencyPeers []string // Previous high latency peer list
115-
lastPersistentlyUnreachable []string // Previous persistently unreachable peer list
114+
lastHighLatencyPeers []string // Previous high latency peer list
115+
lastPersistentlyUnreachable []string // Previous persistently unreachable peer list
116116

117117
*monitors.BaseMonitor
118118
}

0 commit comments

Comments
 (0)