···5959 // ReadSecret reads secret data from the specified HSM path
6060 ReadSecret(ctx context.Context, path string) (SecretData, error)
61616262- // WriteSecret writes secret data to the specified HSM path
6363- WriteSecret(ctx context.Context, path string, data SecretData) error
6464-6565- // WriteSecretWithMetadata writes secret data and metadata to the specified HSM path
6666- WriteSecretWithMetadata(ctx context.Context, path string, data SecretData, metadata *SecretMetadata) error
6262+ // WriteSecret writes secret data and metadata to the specified HSM path
6363+ WriteSecret(ctx context.Context, path string, data SecretData, metadata *SecretMetadata) error
67646865 // ReadMetadata reads metadata for a secret at the given path
6966 ReadMetadata(ctx context.Context, path string) (*SecretMetadata, error)
···367367 return data, nil
368368}
369369370370-// WriteSecretWithMetadata writes secret data and metadata to the specified HSM path
371371-func (c *PKCS11Client) WriteSecretWithMetadata(ctx context.Context, path string, data SecretData, metadata *SecretMetadata) error {
372372- if err := c.WriteSecret(ctx, path, data); err != nil {
373373- return err
374374- }
375375-376376- if metadata != nil {
377377- return c.writeMetadata(path, metadata)
378378- }
379379-380380- return nil
381381-}
382382-383383-// WriteSecret writes secret data to the specified HSM path
384384-func (c *PKCS11Client) WriteSecret(ctx context.Context, path string, data SecretData) error {
370370+// WriteSecret writes secret data and metadata to the specified HSM path
371371+func (c *PKCS11Client) WriteSecret(ctx context.Context, path string, data SecretData, metadata *SecretMetadata) error {
385372 c.mutex.Lock()
386373 defer c.mutex.Unlock()
387374···450437 }
451438452439 c.logger.Info("Successfully wrote secret to HSM", "path", path)
440440+441441+ if metadata != nil {
442442+ return c.writeMetadata(path, metadata)
443443+ }
444444+453445 return nil
454446}
455447
+1-1
internal/hsm/pkcs11_client_nocgo.go
···6060}
61616262// WriteSecret returns an error indicating PKCS#11 is not available
6363-func (c *PKCS11Client) WriteSecret(ctx context.Context, path string, data SecretData) error {
6363+func (c *PKCS11Client) WriteSecret(ctx context.Context, path string, data SecretData, metadata *SecretMetadata) error {
6464 return fmt.Errorf("PKCS#11 support not available: binary was built without CGO")
6565}
6666
+21-57
internal/mirror/manager.go
···2121 "crypto/sha256"
2222 "fmt"
2323 "sort"
2424- "strings"
2524 "time"
26252726 "github.com/go-logr/logr"
···151150152151 // Check if device is connected
153152 if !grpcClient.IsConnected() {
154154- logger.Info("Device not connected", "device", deviceId)
153153+ logger.V(1).Info("Device not connected", "device", deviceId)
155154 for secretPath := range inventory {
156155 inventory[secretPath].DeviceStates[deviceId] = &SecretState{
157156 Present: false,
···180179 data, err := grpcClient.ReadSecret(ctx, secretPath)
181180 if err != nil {
182181 // Secret doesn't exist on this device - leave state.Error = nil so device gets added to devicesNeedingSecret
183183- logger.Info("Secret not found on device", "device", deviceId, "secret", secretPath)
182182+ logger.V(1).Info("Secret not found on device", "device", deviceId, "secret", secretPath)
184183 } else {
185184 // Secret exists, calculate checksum
186185 state.Present = true
187186 state.Checksum = mm.calculateChecksum(data)
188188- logger.Info("Secret found on device", "device", deviceId, "secret", secretPath, "checksum", state.Checksum[:8])
187187+ logger.V(1).Info("Secret found on device", "device", deviceId, "secret", secretPath, "checksum", state.Checksum[:8])
189188190189 // Try to read metadata
191190 metadata, metaErr := grpcClient.ReadMetadata(ctx, secretPath)
···202201 state.Timestamp = timestamp
203202 }
204203 }
205205- logger.Info("Metadata found", "device", deviceId, "secret", secretPath,
204204+ logger.V(1).Info("Metadata found", "device", deviceId, "secret", secretPath,
206205 "version", state.Version, "timestamp", state.Timestamp.Format(time.RFC3339))
207206 } else {
208208- logger.Info("No metadata found", "device", deviceId, "secret", secretPath)
207207+ logger.V(1).Info("No metadata found", "device", deviceId, "secret", secretPath)
209208 }
210209 }
211210···243242 // Analyze all device states for this secret
244243 for deviceName, state := range inventory.DeviceStates {
245244 if state.Error != nil {
246246- logger.Info("Device has error, skipping", "device", deviceName, "secret", secretPath, "error", state.Error)
245245+ logger.V(1).Info("Device has error, skipping", "device", deviceName, "secret", secretPath, "error", state.Error)
247246 continue
248247 }
249248···279278 // Determine sync operation type
280279 if len(devicesWithSecret) == 0 {
281280 // No devices have this secret - nothing to sync
282282- logger.Info("Secret not found on any device", "secret", secretPath)
281281+ logger.V(1).Info("Secret not found on any device", "secret", secretPath)
283282 return nil
284283 }
285284···296295 }
297296298297 if allInSync {
299299- logger.Info("Secret already in sync across all devices", "secret", secretPath)
298298+ logger.V(1).Info("Secret already in sync across all devices", "secret", secretPath)
300299 return &SecretMirrorPlan{
301300 SecretPath: secretPath,
302301 SourceDevice: sourceDevice,
···445444 // Skip if no sync needed
446445 if plan.MirrorType == MirrorTypeSkip {
447446 result.Success = true
448448- logger.Info("Skipping sync - already in sync", "secret", plan.SecretPath)
447447+ logger.V(1).Info("Skipping sync - already in sync", "secret", plan.SecretPath)
449448 return result
450449 }
451450···485484 if plan.MirrorType == MirrorTypeRestoreMetadata {
486485 if sourceMetadata == nil || sourceMetadata.Labels == nil || sourceMetadata.Labels["sync.version"] == "" {
487486 logger.Info("Restoring metadata on source device", "device", plan.SourceDevice, "secret", plan.SecretPath)
488488- if err := mm.writeSecretWithMetadata(ctx, sourceDevice, plan.SecretPath, sourceData, syncMetadata, logger); err != nil {
487487+ if err := mm.WriteSecret(ctx, sourceDevice, plan.SecretPath, sourceData, syncMetadata, logger); err != nil {
489488 result.Error = fmt.Errorf("failed to restore metadata on source: %w", err)
490489 return result
491490 }
···506505 var syncErr error
507506 switch plan.MirrorType {
508507 case MirrorTypeCreate, MirrorTypeUpdate:
509509- syncErr = mm.writeSecretWithMetadata(ctx, targetDevice, plan.SecretPath, sourceData, syncMetadata, logger)
508508+ syncErr = mm.WriteSecret(ctx, targetDevice, plan.SecretPath, sourceData, syncMetadata, logger)
510509 case MirrorTypeRestoreMetadata:
511510 // For metadata restoration, we just update the metadata without changing the data
512511 syncErr = mm.writeMetadataOnly(ctx, targetDevice, plan.SecretPath, syncMetadata, logger)
···554553 // Read metadata (may not exist)
555554 metadata, err := grpcClient.ReadMetadata(ctx, secretPath)
556555 if err != nil {
557557- logger.Info("No metadata found for secret", "secret", secretPath, "device", device.SerialNumber)
556556+ logger.V(1).Info("No metadata found for secret", "secret", secretPath, "device", device.SerialNumber)
558557 metadata = nil // Not an error - metadata may not exist
559558 }
560559561560 return data, metadata, nil
562561}
563562564564-// writeSecretWithMetadata writes both secret data and metadata to a device
565565-func (mm *MirrorManager) writeSecretWithMetadata(ctx context.Context, device hsmv1alpha1.DiscoveredDevice, secretPath string, data hsm.SecretData, metadata *hsm.SecretMetadata, logger logr.Logger) error {
563563+// WriteSecret writes both secret data and metadata to a device
564564+func (mm *MirrorManager) WriteSecret(ctx context.Context, device hsmv1alpha1.DiscoveredDevice, secretPath string, data hsm.SecretData, metadata *hsm.SecretMetadata, logger logr.Logger) error {
566565 grpcClient, err := mm.agentManager.CreateGRPCClient(ctx, device, logger)
567566 if err != nil {
568567 return fmt.Errorf("failed to create gRPC client: %w", err)
···572571 }
573572574573 // Write secret with metadata
575575- if err := grpcClient.WriteSecretWithMetadata(ctx, secretPath, data, metadata); err != nil {
574574+ if err := grpcClient.WriteSecret(ctx, secretPath, data, metadata); err != nil {
576575 return fmt.Errorf("failed to write secret with metadata: %w", err)
577576 }
578577···597596 }
598597599598 // Write secret with updated metadata
600600- if err := grpcClient.WriteSecretWithMetadata(ctx, secretPath, existingData, metadata); err != nil {
599599+ if err := grpcClient.WriteSecret(ctx, secretPath, existingData, metadata); err != nil {
601600 return fmt.Errorf("failed to write secret with metadata: %w", err)
602601 }
603602···730729 // Ensure client is closed after use
731730 defer func() {
732731 if closeErr := hsmClient.Close(); closeErr != nil {
733733- logger.Info("Error closing HSM client", "error", closeErr)
732732+ logger.V(1).Info("Error closing HSM client", "error", closeErr)
734733 }
735734 }()
736735···743742 lastErr = fmt.Errorf("failed to list secrets: %w", err)
744743 attemptLogger.Info("Failed to list secrets on device", "error", err)
745744746746- // Check for specific connection-related errors that might benefit from retry
747747- if isConnectionError(err) && attempt < maxRetries {
748748- backoffDuration := time.Duration(attempt) * time.Second
749749- attemptLogger.Info("Connection error detected, retrying after backoff",
750750- "backoff", backoffDuration.String(), "error", err)
751751- time.Sleep(backoffDuration)
752752- continue
753753- }
754754-755745 if attempt < maxRetries {
756746 backoffDuration := time.Duration(attempt) * time.Second
757747 attemptLogger.Info("Retrying list secrets after backoff", "backoff", backoffDuration.String())
···769759 return nil, fmt.Errorf("failed to discover secrets after %d attempts: %w", maxRetries, lastErr)
770760}
771761772772-// isConnectionError checks if an error is related to connection issues that might benefit from retry
773773-func isConnectionError(err error) bool {
774774- if err == nil {
775775- return false
776776- }
777777-778778- errStr := err.Error()
779779- connectionErrors := []string{
780780- "grpc: the client connection is closing",
781781- "connection refused",
782782- "connection reset",
783783- "connection timeout",
784784- "context deadline exceeded",
785785- "rpc error: code = Canceled",
786786- "rpc error: code = Unavailable",
787787- }
788788-789789- for _, connErr := range connectionErrors {
790790- if strings.Contains(errStr, connErr) {
791791- return true
792792- }
793793- }
794794-795795- return false
796796-}
797797-798762// calculateChecksum calculates SHA256 checksum of secret data
799763func (mm *MirrorManager) calculateChecksum(data hsm.SecretData) string {
800764 if data == nil {
···839803 case <-ticker.C:
840804 devices, err := mm.agentManager.GetAvailableDevices(ctx, mm.operatorNamespace)
841805 if err != nil {
842842- logger.Info("Failed to check available devices", "error", err)
806806+ logger.V(1).Info("Failed to check available devices", "error", err)
843807 continue
844808 }
845809···848812 for _, device := range devices {
849813 grpcClient, err := mm.agentManager.CreateGRPCClient(ctx, device, logger)
850814 if err != nil {
851851- logger.Info("Agent not ready yet", "device", device.SerialNumber, "error", err)
815815+ logger.V(1).Info("Agent not ready yet", "device", device.SerialNumber, "error", err)
852816 continue
853817 }
854818855819 // Test connection
856820 if grpcClient.IsConnected() {
857821 if closeErr := grpcClient.Close(); closeErr != nil {
858858- logger.Info("Failed to close gRPC client", "error", closeErr)
822822+ logger.V(1).Info("Failed to close gRPC client", "error", closeErr)
859823 }
860824 logger.Info("HSM agents are ready", "readyDevices", len(devices))
861825 return true, nil
···863827 }
864828 }
865829866866- logger.Info("Still waiting for agents", "availableDevices", len(devices))
830830+ logger.V(1).Info("Still waiting for agents", "availableDevices", len(devices))
867831 }
868832 }
869833}