diff --git a/internal/service/agent.go b/internal/service/agent.go index ffa4a32..9127c96 100644 --- a/internal/service/agent.go +++ b/internal/service/agent.go @@ -5,6 +5,7 @@ import ( "crypto/sha256" "encoding/hex" "fmt" + "log/slog" "math/rand" "time" @@ -73,7 +74,7 @@ func (s *AgentService) Register(ctx context.Context, name string, hostname strin if err := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "agent_registered", "agent", agent.ID, map[string]interface{}{"name": name, "hostname": hostname}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } // Return the API key only once; the agent must save it securely @@ -96,7 +97,7 @@ func (s *AgentService) HeartbeatWithContext(ctx context.Context, agentID string) if agent.Status != domain.AgentStatusOnline { agent.Status = domain.AgentStatusOnline if err := s.agentRepo.Update(ctx, agent); err != nil { - fmt.Printf("failed to update agent status: %v\n", err) + slog.Error("failed to update agent status", "error", err) } } @@ -140,13 +141,15 @@ func (s *AgentService) SubmitCSR(ctx context.Context, agentID string, certID str } // Record audit event - _ = s.auditService.RecordEvent(ctx, agent.ID, domain.ActorTypeAgent, + if auditErr := s.auditService.RecordEvent(ctx, agent.ID, domain.ActorTypeAgent, "csr_submitted", "certificate", certID, map[string]interface{}{ "agent_hostname": agent.Hostname, "keygen_mode": "agent", "job_id": awaitingJobs[0].ID, - }) + }); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -181,15 +184,17 @@ func (s *AgentService) SubmitCSR(ctx context.Context, agentID string, certID str cert.LastRenewalAt = &now cert.UpdatedAt = now if err := s.certRepo.Update(ctx, cert); err != nil { - fmt.Printf("failed to update certificate: %v\n", err) + slog.Error("failed to update certificate", "error", err) } } } // Record audit event - _ = s.auditService.RecordEvent(ctx, agent.ID, domain.ActorTypeAgent, + if auditErr := s.auditService.RecordEvent(ctx, agent.ID, domain.ActorTypeAgent, "csr_submitted", "certificate", certID, - map[string]interface{}{"agent_hostname": agent.Hostname}) + map[string]interface{}{"agent_hostname": agent.Hostname}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -224,7 +229,7 @@ func (s *AgentService) GetCertificateForAgent(ctx context.Context, agentID strin if err := s.auditService.RecordEvent(ctx, agentID, domain.ActorTypeAgent, "certificate_retrieved", "certificate", certID, map[string]interface{}{"version": latestVersion.SerialNumber}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return []byte(latestVersion.PEMChain), nil @@ -283,7 +288,7 @@ func (s *AgentService) ReportJobStatus(ctx context.Context, agentID string, jobI if err := s.auditService.RecordEvent(ctx, agentID, domain.ActorTypeAgent, "job_status_reported", "job", jobID, map[string]interface{}{"status": status, "error": errMsg}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -302,7 +307,7 @@ func (s *AgentService) MarkStaleAgentsOffline(ctx context.Context, threshold tim if agent.Status == domain.AgentStatusOnline && agent.LastHeartbeatAt != nil && agent.LastHeartbeatAt.Before(cutoff) { agent.Status = domain.AgentStatusOffline if err := s.agentRepo.Update(ctx, agent); err != nil { - fmt.Printf("failed to mark agent %s offline: %v\n", agent.ID, err) + slog.Error("failed to mark agent offline", "agent_id", agent.ID, "error", err) continue } } diff --git a/internal/service/certificate.go b/internal/service/certificate.go index 310de54..b6a1308 100644 --- a/internal/service/certificate.go +++ b/internal/service/certificate.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -62,9 +63,11 @@ func (s *CertificateService) Create(ctx context.Context, cert *domain.ManagedCer if len(violations) > 0 { // Record violations but do not block creation for _, v := range violations { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "policy_violation_detected", "certificate", cert.ID, - map[string]interface{}{"rule_id": v.RuleID, "message": v.Message}) + map[string]interface{}{"rule_id": v.RuleID, "message": v.Message}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } } @@ -78,7 +81,7 @@ func (s *CertificateService) Create(ctx context.Context, cert *domain.ManagedCer "certificate_created", "certificate", cert.ID, map[string]interface{}{"common_name": cert.CommonName}); err != nil { // Log but don't fail the operation - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -98,9 +101,11 @@ func (s *CertificateService) Update(ctx context.Context, cert *domain.ManagedCer } if len(violations) > 0 { for _, v := range violations { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "policy_violation_detected", "certificate", cert.ID, - map[string]interface{}{"rule_id": v.RuleID, "message": v.Message}) + map[string]interface{}{"rule_id": v.RuleID, "message": v.Message}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } } @@ -120,7 +125,7 @@ func (s *CertificateService) Update(ctx context.Context, cert *domain.ManagedCer if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "certificate_updated", "certificate", cert.ID, changes); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -140,7 +145,7 @@ func (s *CertificateService) Archive(ctx context.Context, id string, actor strin if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "certificate_archived", "certificate", id, map[string]interface{}{"common_name": cert.CommonName}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -185,7 +190,7 @@ func (s *CertificateService) TriggerRenewalWithActor(ctx context.Context, certID if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "renewal_triggered", "certificate", certID, map[string]interface{}{"common_name": cert.CommonName}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -207,7 +212,7 @@ func (s *CertificateService) TriggerDeploymentWithActor(ctx context.Context, cer if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "deployment_triggered", "certificate", certID, map[string]interface{}{"common_name": cert.CommonName}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil diff --git a/internal/service/deployment.go b/internal/service/deployment.go index aff4959..0b5c1af 100644 --- a/internal/service/deployment.go +++ b/internal/service/deployment.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -68,7 +69,7 @@ func (s *DeploymentService) CreateDeploymentJobs(ctx context.Context, certID str } if err := s.jobRepo.Create(ctx, job); err != nil { - fmt.Printf("failed to create deployment job for target %s: %v\n", target.ID, err) + slog.Error("failed to create deployment job for target", "target_id", target.ID, "error", err) continue } @@ -80,9 +81,11 @@ func (s *DeploymentService) CreateDeploymentJobs(ctx context.Context, certID str } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "deployment_jobs_created", "certificate", certID, - map[string]interface{}{"target_count": len(targets), "job_count": len(jobIDs)}) + map[string]interface{}{"target_count": len(targets), "job_count": len(jobIDs)}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return jobIDs, nil } @@ -99,7 +102,7 @@ func (s *DeploymentService) ProcessDeploymentJob(ctx context.Context, job *domai if err != nil { updateErr := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusFailed, fmt.Sprintf("certificate fetch failed: %v", err)) if updateErr != nil { - fmt.Printf("failed to update job status: %v\n", updateErr) + slog.Error("failed to update job status", "job_id", job.ID, "error", updateErr) } return fmt.Errorf("failed to fetch certificate: %w", err) } @@ -112,7 +115,7 @@ func (s *DeploymentService) ProcessDeploymentJob(ctx context.Context, job *domai if targetID == "" { updateErr := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusFailed, "target_id not found in job") if updateErr != nil { - fmt.Printf("failed to update job status: %v\n", updateErr) + slog.Error("failed to update job status", "job_id", job.ID, "error", updateErr) } return fmt.Errorf("target_id not found in job") } @@ -121,7 +124,7 @@ func (s *DeploymentService) ProcessDeploymentJob(ctx context.Context, job *domai if err != nil { updateErr := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusFailed, fmt.Sprintf("target fetch failed: %v", err)) if updateErr != nil { - fmt.Printf("failed to update job status: %v\n", updateErr) + slog.Error("failed to update job status", "job_id", job.ID, "error", updateErr) } return fmt.Errorf("failed to fetch target: %w", err) } @@ -132,7 +135,7 @@ func (s *DeploymentService) ProcessDeploymentJob(ctx context.Context, job *domai if err != nil { updateErr := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusFailed, fmt.Sprintf("agent fetch failed: %v", err)) if updateErr != nil { - fmt.Printf("failed to update job status: %v\n", updateErr) + slog.Error("failed to update job status", "job_id", job.ID, "error", updateErr) } return fmt.Errorf("failed to fetch agent: %w", err) } @@ -141,13 +144,17 @@ func (s *DeploymentService) ProcessDeploymentJob(ctx context.Context, job *domai if agent.LastHeartbeatAt != nil && time.Since(*agent.LastHeartbeatAt) > 5*time.Minute { updateErr := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusFailed, "agent is offline") if updateErr != nil { - fmt.Printf("failed to update job status: %v\n", updateErr) + slog.Error("failed to update job status", "job_id", job.ID, "error", updateErr) } - _ = s.notificationSvc.SendDeploymentNotification(ctx, cert, target, false, fmt.Errorf("agent offline")) - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if notifErr := s.notificationSvc.SendDeploymentNotification(ctx, cert, target, false, fmt.Errorf("agent offline")); notifErr != nil { + slog.Error("failed to send deployment notification", "error", notifErr) + } + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "deployment_job_failed", "certificate", job.CertificateID, - map[string]interface{}{"job_id": job.ID, "reason": "agent offline", "target_id": targetID}) + map[string]interface{}{"job_id": job.ID, "reason": "agent offline", "target_id": targetID}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return fmt.Errorf("agent %s is offline", agentID) } @@ -157,9 +164,11 @@ func (s *DeploymentService) ProcessDeploymentJob(ctx context.Context, job *domai // For now, we mark it as pending and rely on agent polling. // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "deployment_job_dispatched", "certificate", job.CertificateID, - map[string]interface{}{"job_id": job.ID, "target_id": targetID, "agent_id": agentID}) + map[string]interface{}{"job_id": job.ID, "target_id": targetID, "agent_id": agentID}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -217,7 +226,7 @@ func (s *DeploymentService) MarkDeploymentComplete(ctx context.Context, jobID st // Fetch certificate and target for notification cert, err := s.certRepo.Get(ctx, job.CertificateID) if err != nil { - fmt.Printf("failed to fetch certificate for notification: %v\n", err) + slog.Error("failed to fetch certificate for notification", "error", err) return nil } @@ -229,20 +238,22 @@ func (s *DeploymentService) MarkDeploymentComplete(ctx context.Context, jobID st if targetID != "" { target, err := s.targetRepo.Get(ctx, targetID) if err != nil { - fmt.Printf("failed to fetch target for notification: %v\n", err) + slog.Error("failed to fetch target for notification", "error", err) return nil } // Send deployment success notification if err := s.notificationSvc.SendDeploymentNotification(ctx, cert, target, true, nil); err != nil { - fmt.Printf("failed to send deployment notification: %v\n", err) + slog.Error("failed to send deployment notification", "error", err) } } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "deployment_job_completed", "certificate", job.CertificateID, - map[string]interface{}{"job_id": jobID, "target_id": targetID}) + map[string]interface{}{"job_id": jobID, "target_id": targetID}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -262,7 +273,7 @@ func (s *DeploymentService) MarkDeploymentFailed(ctx context.Context, jobID stri // Fetch certificate and target for notification cert, err := s.certRepo.Get(ctx, job.CertificateID) if err != nil { - fmt.Printf("failed to fetch certificate for notification: %v\n", err) + slog.Error("failed to fetch certificate for notification", "error", err) return nil } @@ -274,20 +285,22 @@ func (s *DeploymentService) MarkDeploymentFailed(ctx context.Context, jobID stri if targetID != "" { target, err := s.targetRepo.Get(ctx, targetID) if err != nil { - fmt.Printf("failed to fetch target for notification: %v\n", err) + slog.Error("failed to fetch target for notification", "error", err) return nil } // Send deployment failure notification if err := s.notificationSvc.SendDeploymentNotification(ctx, cert, target, false, fmt.Errorf("%s", errMsg)); err != nil { - fmt.Printf("failed to send deployment notification: %v\n", err) + slog.Error("failed to send deployment notification", "error", err) } } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "deployment_job_failed", "certificate", job.CertificateID, - map[string]interface{}{"job_id": jobID, "target_id": targetID, "error": errMsg}) + map[string]interface{}{"job_id": jobID, "target_id": targetID, "error": errMsg}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } diff --git a/internal/service/issuer.go b/internal/service/issuer.go index 677f853..3b5b381 100644 --- a/internal/service/issuer.go +++ b/internal/service/issuer.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -81,7 +82,9 @@ func (s *IssuerService) Create(ctx context.Context, issuer *domain.Issuer, actor } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_issuer", "issuer", issuer.ID, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_issuer", "issuer", issuer.ID, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -99,7 +102,9 @@ func (s *IssuerService) Update(ctx context.Context, id string, issuer *domain.Is } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_issuer", "issuer", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_issuer", "issuer", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -112,7 +117,9 @@ func (s *IssuerService) Delete(ctx context.Context, id string, actor string) err } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_issuer", "issuer", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_issuer", "issuer", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil diff --git a/internal/service/notification.go b/internal/service/notification.go index f0aa592..ea37ac7 100644 --- a/internal/service/notification.go +++ b/internal/service/notification.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -188,7 +189,7 @@ func (s *NotificationService) ProcessPendingNotifications(ctx context.Context) e for _, notif := range pending { if err := s.sendNotification(ctx, notif); err != nil { - fmt.Printf("failed to send notification %s: %v\n", notif.ID, err) + slog.Error("failed to send notification", "notification_id", notif.ID, "error", err) failedCount++ } } @@ -206,20 +207,24 @@ func (s *NotificationService) sendNotification(ctx context.Context, notif *domai notifier, ok := s.notifierRegistry[string(notif.Channel)] if !ok { // No notifier configured for this channel — mark as sent (demo mode) - _ = s.notifRepo.UpdateStatus(ctx, notif.ID, "sent", time.Now()) + if updateErr := s.notifRepo.UpdateStatus(ctx, notif.ID, "sent", time.Now()); updateErr != nil { + slog.Error("failed to update notification status", "notification_id", notif.ID, "error", updateErr) + } return nil } // Send the notification if err := notifier.Send(ctx, notif.Recipient, string(notif.Type), notif.Message); err != nil { // Update status to failed - _ = s.notifRepo.UpdateStatus(ctx, notif.ID, "failed", time.Time{}) + if updateErr := s.notifRepo.UpdateStatus(ctx, notif.ID, "failed", time.Time{}); updateErr != nil { + slog.Error("failed to update notification status", "notification_id", notif.ID, "error", updateErr) + } return fmt.Errorf("failed to send via %s: %w", notif.Channel, err) } // Update status to sent if err := s.notifRepo.UpdateStatus(ctx, notif.ID, "sent", time.Now()); err != nil { - fmt.Printf("failed to update notification status: %v\n", err) + slog.Error("failed to update notification status", "notification_id", notif.ID, "error", err) } return nil diff --git a/internal/service/owner.go b/internal/service/owner.go index 95c4d70..d3eff7e 100644 --- a/internal/service/owner.go +++ b/internal/service/owner.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -81,7 +82,9 @@ func (s *OwnerService) Create(ctx context.Context, owner *domain.Owner, actor st } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_owner", "owner", owner.ID, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_owner", "owner", owner.ID, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -99,7 +102,9 @@ func (s *OwnerService) Update(ctx context.Context, id string, owner *domain.Owne } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_owner", "owner", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_owner", "owner", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -112,7 +117,9 @@ func (s *OwnerService) Delete(ctx context.Context, id string, actor string) erro } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_owner", "owner", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_owner", "owner", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil diff --git a/internal/service/policy.go b/internal/service/policy.go index b1ed8b2..6b94d75 100644 --- a/internal/service/policy.go +++ b/internal/service/policy.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -44,7 +45,7 @@ func (s *PolicyService) ValidateCertificate(ctx context.Context, cert *domain.Ma // Evaluate rule against certificate v, err := s.evaluateRule(rule, cert) if err != nil { - fmt.Printf("failed to evaluate rule %s: %v\n", rule.ID, err) + slog.Error("failed to evaluate rule", "rule_id", rule.ID, "error", err) continue } @@ -149,7 +150,7 @@ func (s *PolicyService) CreateRule(ctx context.Context, rule *domain.PolicyRule, if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "policy_rule_created", "policy", rule.ID, map[string]interface{}{"rule_type": rule.Type}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -175,7 +176,7 @@ func (s *PolicyService) UpdateRule(ctx context.Context, rule *domain.PolicyRule, if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "policy_rule_updated", "policy", rule.ID, changes); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil @@ -213,7 +214,7 @@ func (s *PolicyService) DeleteRule(ctx context.Context, id string, actor string) if err := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "policy_rule_deleted", "policy", id, map[string]interface{}{"rule_type": rule.Type}); err != nil { - fmt.Printf("failed to record audit event: %v\n", err) + slog.Error("failed to record audit event", "error", err) } return nil diff --git a/internal/service/renewal.go b/internal/service/renewal.go index 10c427a..92700eb 100644 --- a/internal/service/renewal.go +++ b/internal/service/renewal.go @@ -10,6 +10,7 @@ import ( "encoding/hex" "encoding/pem" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -103,8 +104,7 @@ func (s *RenewalService) CheckExpiringCertificates(ctx context.Context) error { policy, err = s.renewalPolicyRepo.Get(ctx, cert.RenewalPolicyID) if err != nil { // Log but continue with defaults - fmt.Printf("failed to fetch renewal policy %s for cert %s, using defaults: %v\n", - cert.RenewalPolicyID, cert.ID, err) + slog.Error("failed to fetch renewal policy, using defaults", "policy_id", cert.RenewalPolicyID, "cert_id", cert.ID, "error", err) } else { policyCache[cert.RenewalPolicyID] = policy } @@ -153,20 +153,22 @@ func (s *RenewalService) CheckExpiringCertificates(ctx context.Context) error { } if err := s.jobRepo.Create(ctx, job); err != nil { - fmt.Printf("failed to create renewal job for cert %s: %v\n", cert.ID, err) + slog.Error("failed to create renewal job for cert", "cert_id", cert.ID, "error", err) continue } // Update certificate status to RenewalInProgress cert.Status = domain.CertificateStatusRenewalInProgress if err := s.certRepo.Update(ctx, cert); err != nil { - fmt.Printf("failed to update cert status for %s: %v\n", cert.ID, err) + slog.Error("failed to update cert status", "cert_id", cert.ID, "error", err) } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "renewal_job_created", "certificate", cert.ID, - map[string]interface{}{"days_until_expiry": daysUntil, "job_id": job.ID}) + map[string]interface{}{"days_until_expiry": daysUntil, "job_id": job.ID}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -186,8 +188,7 @@ func (s *RenewalService) sendThresholdAlerts(ctx context.Context, cert *domain.M // Check if we already sent a notification for this threshold (deduplication) alreadySent, err := s.notificationSvc.HasThresholdNotification(ctx, cert.ID, threshold) if err != nil { - fmt.Printf("failed to check notification dedup for cert %s threshold %d: %v\n", - cert.ID, threshold, err) + slog.Error("failed to check notification dedup", "cert_id", cert.ID, "threshold", threshold, "error", err) continue } if alreadySent { @@ -196,17 +197,18 @@ func (s *RenewalService) sendThresholdAlerts(ctx context.Context, cert *domain.M // Send the threshold alert if err := s.notificationSvc.SendThresholdAlert(ctx, cert, daysUntil, threshold); err != nil { - fmt.Printf("failed to send threshold alert for cert %s at %d days: %v\n", - cert.ID, threshold, err) + slog.Error("failed to send threshold alert for cert", "cert_id", cert.ID, "threshold", threshold, "error", err) } // Record audit event for the alert - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "expiration_alert_sent", "certificate", cert.ID, map[string]interface{}{ "threshold_days": threshold, "days_until_expiry": daysUntil, - }) + }); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } } @@ -234,7 +236,7 @@ func (s *RenewalService) updateCertExpiryStatus(ctx context.Context, cert *domai cert.Status = newStatus cert.UpdatedAt = time.Now() if err := s.certRepo.Update(ctx, cert); err != nil { - fmt.Printf("failed to update cert %s status to %s: %v\n", cert.ID, newStatus, err) + slog.Error("failed to update cert status", "cert_id", cert.ID, "new_status", newStatus, "error", err) } } @@ -290,13 +292,15 @@ func (s *RenewalService) processRenewalAgentKeygen(ctx context.Context, job *dom cert.Status = domain.CertificateStatusRenewalInProgress cert.UpdatedAt = time.Now() if err := s.certRepo.Update(ctx, cert); err != nil { - fmt.Printf("failed to update cert status for %s: %v\n", cert.ID, err) + slog.Error("failed to update cert status", "cert_id", cert.ID, "error", err) } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "renewal_awaiting_csr", "certificate", job.CertificateID, - map[string]interface{}{"job_id": job.ID, "keygen_mode": "agent"}) + map[string]interface{}{"job_id": job.ID, "keygen_mode": "agent"}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -343,10 +347,14 @@ func (s *RenewalService) processRenewalServerKeygen(ctx context.Context, job *do result, err := connector.RenewCertificate(ctx, cert.CommonName, cert.SANs, csrPEM) if err != nil { s.failJob(ctx, job, fmt.Sprintf("issuer renewal failed: %v", err)) - _ = s.notificationSvc.SendRenewalNotification(ctx, cert, false, err) - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if notifErr := s.notificationSvc.SendRenewalNotification(ctx, cert, false, err); notifErr != nil { + slog.Error("failed to send renewal failure notification", "error", notifErr) + } + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "renewal_job_failed", "certificate", job.CertificateID, - map[string]interface{}{"job_id": job.ID, "error": err.Error()}) + map[string]interface{}{"job_id": job.ID, "error": err.Error()}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return fmt.Errorf("issuer renewal failed: %w", err) } @@ -392,18 +400,20 @@ func (s *RenewalService) processRenewalServerKeygen(ctx context.Context, job *do // Send success notification if err := s.notificationSvc.SendRenewalNotification(ctx, cert, true, nil); err != nil { - fmt.Printf("failed to send renewal notification: %v\n", err) + slog.Error("failed to send renewal notification", "error", err) } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "renewal_job_completed", "certificate", job.CertificateID, map[string]interface{}{ "job_id": job.ID, "serial": result.Serial, "not_after": result.NotAfter, "keygen_mode": "server", - }) + }); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -427,10 +437,14 @@ func (s *RenewalService) CompleteAgentCSRRenewal(ctx context.Context, job *domai result, err := connector.RenewCertificate(ctx, cert.CommonName, cert.SANs, csrPEM) if err != nil { s.failJob(ctx, job, fmt.Sprintf("issuer signing failed: %v", err)) - _ = s.notificationSvc.SendRenewalNotification(ctx, cert, false, err) - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if notifErr := s.notificationSvc.SendRenewalNotification(ctx, cert, false, err); notifErr != nil { + slog.Error("failed to send renewal failure notification", "error", notifErr) + } + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "renewal_job_failed", "certificate", job.CertificateID, - map[string]interface{}{"job_id": job.ID, "error": err.Error()}) + map[string]interface{}{"job_id": job.ID, "error": err.Error()}); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return fmt.Errorf("issuer signing failed: %w", err) } @@ -475,18 +489,20 @@ func (s *RenewalService) CompleteAgentCSRRenewal(ctx context.Context, job *domai // Send success notification if err := s.notificationSvc.SendRenewalNotification(ctx, cert, true, nil); err != nil { - fmt.Printf("failed to send renewal notification: %v\n", err) + slog.Error("failed to send renewal notification", "error", err) } // Record audit event - _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, + if auditErr := s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, "renewal_job_completed", "certificate", cert.ID, map[string]interface{}{ "job_id": job.ID, "serial": result.Serial, "not_after": result.NotAfter, "keygen_mode": "agent", - }) + }); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } return nil } @@ -509,7 +525,7 @@ func (s *RenewalService) createDeploymentJobs(ctx context.Context, cert *domain. CreatedAt: time.Now(), } if err := s.jobRepo.Create(ctx, deployJob); err != nil { - fmt.Printf("failed to create deployment job for target %s: %v\n", targetID, err) + slog.Error("failed to create deployment job for target", "target_id", targetID, "error", err) } } } @@ -532,7 +548,7 @@ func (s *RenewalService) GetAwaitingCSRJobs(ctx context.Context, certID string) // failJob is a helper to mark a job as failed with an error message. func (s *RenewalService) failJob(ctx context.Context, job *domain.Job, errMsg string) { if updateErr := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusFailed, errMsg); updateErr != nil { - fmt.Printf("failed to update job status: %v\n", updateErr) + slog.Error("failed to update job status", "job_id", job.ID, "error", updateErr) } } @@ -565,7 +581,7 @@ func (s *RenewalService) RetryFailedJobs(ctx context.Context, maxRetries int) er // Reset status to pending for retry if err := s.jobRepo.UpdateStatus(ctx, job.ID, domain.JobStatusPending, ""); err != nil { - fmt.Printf("failed to reset job status for retry: %v\n", err) + slog.Error("failed to reset job status for retry", "job_id", job.ID, "error", err) continue } } diff --git a/internal/service/target.go b/internal/service/target.go index 79396d4..9785599 100644 --- a/internal/service/target.go +++ b/internal/service/target.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -81,7 +82,9 @@ func (s *TargetService) Create(ctx context.Context, target *domain.DeploymentTar } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_target", "target", target.ID, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_target", "target", target.ID, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -99,7 +102,9 @@ func (s *TargetService) Update(ctx context.Context, id string, target *domain.De } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_target", "target", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_target", "target", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -112,7 +117,9 @@ func (s *TargetService) Delete(ctx context.Context, id string, actor string) err } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_target", "target", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_target", "target", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil diff --git a/internal/service/team.go b/internal/service/team.go index de4fd3b..eed0c77 100644 --- a/internal/service/team.go +++ b/internal/service/team.go @@ -3,6 +3,7 @@ package service import ( "context" "fmt" + "log/slog" "time" "github.com/shankar0123/certctl/internal/domain" @@ -81,7 +82,9 @@ func (s *TeamService) Create(ctx context.Context, team *domain.Team, actor strin } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_team", "team", team.ID, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_team", "team", team.ID, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -99,7 +102,9 @@ func (s *TeamService) Update(ctx context.Context, id string, team *domain.Team, } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_team", "team", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_team", "team", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil @@ -112,7 +117,9 @@ func (s *TeamService) Delete(ctx context.Context, id string, actor string) error } if s.auditService != nil { - _ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_team", "team", id, nil) + if auditErr := s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_team", "team", id, nil); auditErr != nil { + slog.Error("failed to record audit event", "error", auditErr) + } } return nil