A Kubernetes operator that bridges Hardware Security Module (HSM) data storage with Kubernetes Secrets, providing true secret portability th
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix lint

+38 -22
+2 -1
cmd/agent/main.go
··· 65 65 if deviceName == "" { 66 66 deviceName = os.Getenv("HSM_DEVICE_NAME") 67 67 if deviceName == "" { 68 - setupLog.Error(fmt.Errorf("device name required"), "Device name must be provided via --device-name or HSM_DEVICE_NAME environment variable") 68 + setupLog.Error(fmt.Errorf("device name required"), 69 + "Device name must be provided via --device-name or HSM_DEVICE_NAME environment variable") 69 70 os.Exit(1) 70 71 } 71 72 }
+8 -4
internal/agent/client.go
··· 146 146 secretData[key] = v 147 147 case []interface{}: 148 148 // Handle JSON array (byte array) 149 - bytes := make([]byte, len(v)) 149 + byteArray := make([]byte, len(v)) 150 150 for i, b := range v { 151 151 if byteVal, ok := b.(float64); ok { 152 - bytes[i] = byte(byteVal) 152 + byteArray[i] = byte(byteVal) 153 153 } 154 154 } 155 - secretData[key] = bytes 155 + secretData[key] = byteArray 156 156 default: 157 157 // Convert to string as fallback 158 158 secretData[key] = []byte(fmt.Sprintf("%v", v)) ··· 329 329 continue 330 330 } 331 331 332 - defer resp.Body.Close() 332 + defer func() { 333 + if err := resp.Body.Close(); err != nil { 334 + c.logger.V(1).Info("Failed to close response body", "error", err) 335 + } 336 + }() 333 337 334 338 // Read response body 335 339 bodyBytes, err := io.ReadAll(resp.Body)
+3 -2
internal/agent/deployment.go
··· 55 55 } 56 56 57 57 // NewManager creates a new agent manager 58 - func NewManager(client client.Client, agentImage, namespace string) *Manager { 58 + func NewManager(k8sClient client.Client, agentImage, namespace string) *Manager { 59 59 if agentImage == "" { 60 60 agentImage = AgentImage 61 61 } ··· 64 64 } 65 65 66 66 return &Manager{ 67 - Client: client, 67 + Client: k8sClient, 68 68 AgentImage: agentImage, 69 69 AgentNamespace: namespace, 70 70 } ··· 374 374 if hsmDevice.Spec.NodeSelector != nil { 375 375 // This would need more sophisticated logic to map selectors to actual nodes 376 376 // For now, return empty to indicate no target found 377 + return "" 377 378 } 378 379 379 380 return ""
+25 -15
internal/agent/server.go
··· 99 99 v1 := s.router.Group("/api/v1") 100 100 { 101 101 // HSM operations 102 - hsm := v1.Group("/hsm") 102 + hsmGroup := v1.Group("/hsm") 103 103 { 104 - hsm.GET("/info", s.handleGetInfo) 105 - hsm.GET("/secrets/:path", s.handleReadSecret) 106 - hsm.POST("/secrets/:path", s.handleWriteSecret) 107 - hsm.PUT("/secrets/:path", s.handleWriteSecret) 108 - hsm.DELETE("/secrets/:path", s.handleDeleteSecret) 109 - hsm.GET("/secrets", s.handleListSecrets) 110 - hsm.GET("/checksum/:path", s.handleGetChecksum) 104 + hsmGroup.GET("/info", s.handleGetInfo) 105 + hsmGroup.GET("/secrets/:path", s.handleReadSecret) 106 + hsmGroup.POST("/secrets/:path", s.handleWriteSecret) 107 + hsmGroup.PUT("/secrets/:path", s.handleWriteSecret) 108 + hsmGroup.DELETE("/secrets/:path", s.handleDeleteSecret) 109 + hsmGroup.GET("/secrets", s.handleListSecrets) 110 + hsmGroup.GET("/checksum/:path", s.handleGetChecksum) 111 111 } 112 112 } 113 113 ··· 153 153 defer cancel() 154 154 155 155 s.logger.Info("Shutting down servers") 156 - healthServer.Shutdown(shutdownCtx) 157 - server.Shutdown(shutdownCtx) 156 + if err := healthServer.Shutdown(shutdownCtx); err != nil { 157 + s.logger.Error(err, "Failed to shutdown health server") 158 + } 159 + if err := server.Shutdown(shutdownCtx); err != nil { 160 + s.logger.Error(err, "Failed to shutdown main server") 161 + } 158 162 }() 159 163 160 164 s.logger.Info("Starting HSM agent server", "port", s.port, "device", s.deviceName) ··· 283 287 "checksum": checksum, 284 288 } 285 289 286 - s.sendResponse(c, http.StatusOK, "Secret written successfully", response) 290 + s.sendResponse(c, http.StatusCreated, "Secret written successfully", response) 287 291 } 288 292 289 293 // handleDeleteSecret handles secret deletion requests ··· 398 402 399 403 w.Header().Set("Content-Type", "application/json") 400 404 // Simple JSON encoding without external dependencies 401 - fmt.Fprintf(w, `{"status":"%s","deviceName":"%s","hsmConnected":%t,"timestamp":"%s"}`, 402 - status.Status, status.DeviceName, status.HSMConnected, status.Timestamp.Format(time.RFC3339)) 405 + if _, err := fmt.Fprintf(w, `{"status":"%s","deviceName":"%s","hsmConnected":%t,"timestamp":"%s"}`, 406 + status.Status, status.DeviceName, status.HSMConnected, status.Timestamp.Format(time.RFC3339)); err != nil { 407 + s.logger.Error(err, "Failed to write health response") 408 + } 403 409 } 404 410 405 411 // handleReadyz handles readiness probe requests ··· 408 414 if s.hsmClient == nil || !s.hsmClient.IsConnected() { 409 415 w.WriteHeader(http.StatusServiceUnavailable) 410 416 w.Header().Set("Content-Type", "application/json") 411 - fmt.Fprintf(w, `{"status":"not_ready","reason":"hsm_not_connected"}`) 417 + if _, err := fmt.Fprintf(w, `{"status":"not_ready","reason":"hsm_not_connected"}`); err != nil { 418 + s.logger.Error(err, "Failed to write readiness response") 419 + } 412 420 return 413 421 } 414 422 415 423 w.WriteHeader(http.StatusOK) 416 424 w.Header().Set("Content-Type", "application/json") 417 - fmt.Fprintf(w, `{"status":"ready"}`) 425 + if _, err := fmt.Fprintf(w, `{"status":"ready"}`); err != nil { 426 + s.logger.Error(err, "Failed to write readiness response") 427 + } 418 428 } 419 429 420 430 // sendResponse sends a successful API response