chore(fmt): repo-wide gofmt -w sweep — close drift surfaced by ci-pipeline-cleanup Phase 4

Mechanical reformat. The new 'gofmt drift' CI step (added in
ci-pipeline-cleanup Phase 4, commit 71b2245) surfaced 111 files
with accumulated gofmt drift across cmd/, internal/, and deploy/test/.

Each file's diff is gofmt-standard: whitespace adjustments, intra-
group import sorting (alphabetical by import path within blank-line-
separated groups), and struct-tag column alignment. No semantic
changes — verified via 'git diff --ignore-all-space' which shows only
the line-position deltas from import reordering.

The gate stays in place after this commit. Going forward it catches
gofmt drift at PR time.
This commit is contained in:
shankar0123
2026-04-30 22:33:57 +00:00
parent 251db46f26
commit 482c7e8047
111 changed files with 761 additions and 770 deletions
+10 -10
View File
@@ -12,16 +12,16 @@ import (
// mockAgentGroupRepo is a test implementation of AgentGroupRepository
type mockAgentGroupRepo struct {
groups map[string]*domain.AgentGroup
members map[string][]*domain.Agent
CreateErr error
UpdateErr error
DeleteErr error
GetErr error
ListErr error
ListMembersErr error
AddMemberErr error
RemoveMemberErr error
groups map[string]*domain.AgentGroup
members map[string][]*domain.Agent
CreateErr error
UpdateErr error
DeleteErr error
GetErr error
ListErr error
ListMembersErr error
AddMemberErr error
RemoveMemberErr error
}
func newMockAgentGroupRepository() *mockAgentGroupRepo {
+3 -3
View File
@@ -109,9 +109,9 @@ func TestAgentService_UpdateJobStatus_DelegatesToReportJobStatus(t *testing.T) {
svc, repo, _, jobRepo, _ := newTestAgentSvc(t)
repo.Agents["a-1"] = &domain.Agent{ID: "a-1", Status: domain.AgentStatusOnline}
jobRepo.Jobs["j-1"] = &domain.Job{
ID: "j-1",
AgentID: strPtr("a-1"),
Status: domain.JobStatusRunning,
ID: "j-1",
AgentID: strPtr("a-1"),
Status: domain.JobStatusRunning,
}
err := svc.UpdateJobStatus(context.Background(), "a-1", "j-1", "Completed", "")
if err != nil {
-1
View File
@@ -10,7 +10,6 @@ import (
"github.com/shankar0123/certctl/internal/domain"
)
func TestRegisterAgent(t *testing.T) {
ctx := context.Background()
agentRepo := &mockAgentRepo{
+22 -22
View File
@@ -73,29 +73,29 @@ var credentialKeys = map[string]bool{
// Note `ip_address` is debatable — useful for forensics but flagged by
// GDPR Art. 32 — defaulting to redact, operators can audit + adjust.
var piiKeys = map[string]bool{
"email": true,
"email_address": true,
"phone": true,
"phone_number": true,
"telephone": true,
"ssn": true,
"email": true,
"email_address": true,
"phone": true,
"phone_number": true,
"telephone": true,
"ssn": true,
"social_security": true,
"dob": true,
"date_of_birth": true,
"name": true,
"full_name": true,
"first_name": true,
"last_name": true,
"surname": true,
"address": true,
"street": true,
"street_address": true,
"city": true,
"postal_code": true,
"zip": true,
"zipcode": true,
"ip": true,
"ip_address": true,
"dob": true,
"date_of_birth": true,
"name": true,
"full_name": true,
"first_name": true,
"last_name": true,
"surname": true,
"address": true,
"street": true,
"street_address": true,
"city": true,
"postal_code": true,
"zip": true,
"zipcode": true,
"ip": true,
"ip_address": true,
}
// RedactDetailsForAudit walks a details map and returns a NEW map with
+8 -8
View File
@@ -30,8 +30,8 @@ func TestRedactDetailsForAudit_CredentialKeys(t *testing.T) {
for _, key := range cases {
t.Run(key, func(t *testing.T) {
in := map[string]interface{}{
key: "sensitive-value-do-not-leak",
"non_sensitive_id": "ok-public-id",
key: "sensitive-value-do-not-leak",
"non_sensitive_id": "ok-public-id",
}
out := RedactDetailsForAudit(in)
if out[key] != "[REDACTED:CREDENTIAL]" {
@@ -70,7 +70,7 @@ func TestRedactDetailsForAudit_NestedMap(t *testing.T) {
in := map[string]interface{}{
"resource_id": "iss-prod",
"config": map[string]interface{}{
"endpoint": "https://acme.example.com",
"endpoint": "https://acme.example.com",
"eab_secret": "do-not-leak-this-secret",
"contact": map[string]interface{}{
"email": "ops@example.com",
@@ -159,8 +159,8 @@ func TestRedactDetailsForAudit_NoRedactionPath(t *testing.T) {
// Maps with no sensitive keys should NOT have a redacted_keys array
// — clutter-free for the common case.
in := map[string]interface{}{
"action": "create_certificate",
"cert_id": "mc-prod-001",
"action": "create_certificate",
"cert_id": "mc-prod-001",
"latency_ms": float64(42),
}
out := RedactDetailsForAudit(in)
@@ -171,7 +171,7 @@ func TestRedactDetailsForAudit_NoRedactionPath(t *testing.T) {
func TestRedactDetailsForAudit_DoesNotMutateInput(t *testing.T) {
in := map[string]interface{}{
"api_key": "secret-do-not-leak",
"api_key": "secret-do-not-leak",
"resource": "iss-prod",
}
_ = RedactDetailsForAudit(in)
@@ -197,8 +197,8 @@ func TestRedactDetailsForAudit_JSONRoundTrip(t *testing.T) {
// The redacted map MUST round-trip through json.Marshal (the
// AuditService persistence path). Catches type-assertion regressions.
in := map[string]interface{}{
"reason": "compromised-key",
"api_key": "leak-me",
"reason": "compromised-key",
"api_key": "leak-me",
"contacts": []interface{}{
map[string]interface{}{"email": "ops@example.com"},
},
+2 -2
View File
@@ -67,8 +67,8 @@ func TestBulkReassign_HappyPath(t *testing.T) {
func TestBulkReassign_SkipsAlreadyOwned(t *testing.T) {
svc, certRepo, ownerRepo, _ := newBulkReassignmentTestService()
addOwner(ownerRepo, "o-bob")
addOwnedCert(certRepo, "mc-1", "o-bob", "") // already owned by target
addOwnedCert(certRepo, "mc-2", "o-alice", "") // needs reassign
addOwnedCert(certRepo, "mc-1", "o-bob", "") // already owned by target
addOwnedCert(certRepo, "mc-2", "o-alice", "") // needs reassign
res, err := svc.BulkReassign(context.Background(),
domain.BulkReassignmentRequest{
+14 -14
View File
@@ -32,11 +32,11 @@ func newBulkRevocationTestService() (*BulkRevocationService, *mockCertRepo, *moc
func addTestCert(repo *mockCertRepo, id, status, issuerID string) {
cert := &domain.ManagedCertificate{
ID: id,
ID: id,
CommonName: id + ".example.com",
Status: domain.CertificateStatus(status),
IssuerID: issuerID,
ExpiresAt: time.Now().AddDate(0, 6, 0),
Status: domain.CertificateStatus(status),
IssuerID: issuerID,
ExpiresAt: time.Now().AddDate(0, 6, 0),
}
repo.AddCert(cert)
// Add a version with serial number (needed by RevokeCertificateWithActor)
@@ -54,13 +54,13 @@ func addTestCert(repo *mockCertRepo, id, status, issuerID string) {
func addTestCertWithProfile(repo *mockCertRepo, id, status, issuerID, profileID, ownerID string) {
cert := &domain.ManagedCertificate{
ID: id,
CommonName: id + ".example.com",
Status: domain.CertificateStatus(status),
IssuerID: issuerID,
ID: id,
CommonName: id + ".example.com",
Status: domain.CertificateStatus(status),
IssuerID: issuerID,
CertificateProfileID: profileID,
OwnerID: ownerID,
ExpiresAt: time.Now().AddDate(0, 6, 0),
OwnerID: ownerID,
ExpiresAt: time.Now().AddDate(0, 6, 0),
}
repo.AddCert(cert)
repo.Versions[id] = []*domain.CertificateVersion{
@@ -272,11 +272,11 @@ func TestBulkRevoke_PartialFailure(t *testing.T) {
addTestCert(certRepo, "mc-1", "Active", "iss-local")
// mc-2 is active but has NO version — RevokeCertificateWithActor will fail on GetLatestVersion
cert2 := &domain.ManagedCertificate{
ID: "mc-2",
ID: "mc-2",
CommonName: "mc-2.example.com",
Status: domain.CertificateStatusActive,
IssuerID: "iss-local",
ExpiresAt: time.Now().AddDate(0, 6, 0),
Status: domain.CertificateStatusActive,
IssuerID: "iss-local",
ExpiresAt: time.Now().AddDate(0, 6, 0),
}
certRepo.AddCert(cert2)
// Don't add versions for mc-2 so GetLatestVersion returns errNotFound
+11 -11
View File
@@ -266,17 +266,17 @@ func TestDeploymentService_ProcessDeploymentJob_Success(t *testing.T) {
// Add agent with recent heartbeat
now := time.Now()
agent := &domain.Agent{
ID: "agent-1",
Name: "Test Agent",
Hostname: "agent.example.com",
Status: domain.AgentStatusOnline,
LastHeartbeatAt: &now,
RegisteredAt: time.Now(),
APIKeyHash: "hash-1",
OS: "linux",
Architecture: "amd64",
IPAddress: "192.168.1.1",
Version: "1.0.0",
ID: "agent-1",
Name: "Test Agent",
Hostname: "agent.example.com",
Status: domain.AgentStatusOnline,
LastHeartbeatAt: &now,
RegisteredAt: time.Now(),
APIKeyHash: "hash-1",
OS: "linux",
Architecture: "amd64",
IPAddress: "192.168.1.1",
Version: "1.0.0",
}
agentRepo.AddAgent(agent)
+14 -14
View File
@@ -31,20 +31,20 @@ type HTMLEmailSender interface {
// DigestData holds the aggregated data for a digest email.
type DigestData struct {
GeneratedAt time.Time `json:"generated_at"`
TotalCertificates int64 `json:"total_certificates"`
ExpiringCertificates int64 `json:"expiring_certificates"`
ExpiredCertificates int64 `json:"expired_certificates"`
RevokedCertificates int64 `json:"revoked_certificates"`
ActiveAgents int64 `json:"active_agents"`
OfflineAgents int64 `json:"offline_agents"`
TotalAgents int64 `json:"total_agents"`
PendingJobs int64 `json:"pending_jobs"`
FailedJobs int64 `json:"failed_jobs"`
CompletedJobs int64 `json:"completed_jobs"`
ExpiringCerts []DigestCertEntry `json:"expiring_certs"`
RecentFailures []DigestJobEntry `json:"recent_failures"`
StatusCounts []DigestStatusCount `json:"status_counts"`
GeneratedAt time.Time `json:"generated_at"`
TotalCertificates int64 `json:"total_certificates"`
ExpiringCertificates int64 `json:"expiring_certificates"`
ExpiredCertificates int64 `json:"expired_certificates"`
RevokedCertificates int64 `json:"revoked_certificates"`
ActiveAgents int64 `json:"active_agents"`
OfflineAgents int64 `json:"offline_agents"`
TotalAgents int64 `json:"total_agents"`
PendingJobs int64 `json:"pending_jobs"`
FailedJobs int64 `json:"failed_jobs"`
CompletedJobs int64 `json:"completed_jobs"`
ExpiringCerts []DigestCertEntry `json:"expiring_certs"`
RecentFailures []DigestJobEntry `json:"recent_failures"`
StatusCounts []DigestStatusCount `json:"status_counts"`
}
// DigestCertEntry represents a certificate entry in the digest.
+54 -54
View File
@@ -12,17 +12,17 @@ import (
// mockDiscoveryRepo is a test implementation of DiscoveryRepository
type mockDiscoveryRepo struct {
Scans map[string]*domain.DiscoveryScan
Discovered map[string]*domain.DiscoveredCertificate
CreateScanErr error
GetScanErr error
ListScansErr error
Scans map[string]*domain.DiscoveryScan
Discovered map[string]*domain.DiscoveredCertificate
CreateScanErr error
GetScanErr error
ListScansErr error
CreateDiscoveredErr error
GetDiscoveredErr error
ListDiscoveredErr error
UpdateStatusErr error
GetDiscoveredErr error
ListDiscoveredErr error
UpdateStatusErr error
GetByFingerprintErr error
CountByStatusErr error
CountByStatusErr error
}
func newMockDiscoveryRepository() *mockDiscoveryRepo {
@@ -268,20 +268,20 @@ func TestListDiscovered_Success(t *testing.T) {
now := time.Now()
cert1 := &domain.DiscoveredCertificate{
ID: "dcert-1",
AgentID: "agent-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
ID: "dcert-1",
AgentID: "agent-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
cert2 := &domain.DiscoveredCertificate{
ID: "dcert-2",
AgentID: "agent-1",
CommonName: "api.example.com",
Status: domain.DiscoveryStatusManaged,
CreatedAt: now,
UpdatedAt: now,
ID: "dcert-2",
AgentID: "agent-1",
CommonName: "api.example.com",
Status: domain.DiscoveryStatusManaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[cert1.ID] = cert1
discoveryRepo.Discovered[cert2.ID] = cert2
@@ -304,20 +304,20 @@ func TestListDiscovered_WithStatusFilter(t *testing.T) {
now := time.Now()
cert1 := &domain.DiscoveredCertificate{
ID: "dcert-1",
AgentID: "agent-1",
ID: "dcert-1",
AgentID: "agent-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
cert2 := &domain.DiscoveredCertificate{
ID: "dcert-2",
AgentID: "agent-1",
ID: "dcert-2",
AgentID: "agent-1",
CommonName: "api.example.com",
Status: domain.DiscoveryStatusManaged,
CreatedAt: now,
UpdatedAt: now,
Status: domain.DiscoveryStatusManaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[cert1.ID] = cert1
discoveryRepo.Discovered[cert2.ID] = cert2
@@ -340,11 +340,11 @@ func TestGetDiscovered_Success(t *testing.T) {
now := time.Now()
cert := &domain.DiscoveredCertificate{
ID: "dcert-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
ID: "dcert-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[cert.ID] = cert
@@ -363,12 +363,12 @@ func TestClaimDiscovered_Success(t *testing.T) {
now := time.Now()
discoveredCert := &domain.DiscoveredCertificate{
ID: "dcert-1",
CommonName: "example.com",
FingerprintSHA256: "abc123",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
ID: "dcert-1",
CommonName: "example.com",
FingerprintSHA256: "abc123",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[discoveredCert.ID] = discoveredCert
@@ -415,11 +415,11 @@ func TestClaimDiscovered_MissingManagedCertID(t *testing.T) {
now := time.Now()
cert := &domain.DiscoveredCertificate{
ID: "dcert-1",
ID: "dcert-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[cert.ID] = cert
@@ -434,11 +434,11 @@ func TestClaimDiscovered_ManagedCertNotFound(t *testing.T) {
now := time.Now()
cert := &domain.DiscoveredCertificate{
ID: "dcert-1",
ID: "dcert-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[cert.ID] = cert
@@ -456,11 +456,11 @@ func TestDismissDiscovered_Success(t *testing.T) {
now := time.Now()
cert := &domain.DiscoveredCertificate{
ID: "dcert-1",
ID: "dcert-1",
CommonName: "example.com",
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
Status: domain.DiscoveryStatusUnmanaged,
CreatedAt: now,
UpdatedAt: now,
}
discoveryRepo.Discovered[cert.ID] = cert
+3 -3
View File
@@ -71,10 +71,10 @@ func TestExportPEM_Success(t *testing.T) {
Status: domain.CertificateStatusActive,
},
&domain.CertificateVersion{
ID: "cv-1",
ID: "cv-1",
CertificateID: "mc-test-1",
SerialNumber: "abc123",
PEMChain: fullPEM,
SerialNumber: "abc123",
PEMChain: fullPEM,
},
)
auditSvc := &AuditService{auditRepo: &mockAuditRepo{}}
+16 -16
View File
@@ -14,19 +14,19 @@ import (
// mockHealthCheckRepo implements the HealthCheckRepository interface for testing.
type mockHealthCheckRepo struct {
checks map[string]*domain.EndpointHealthCheck
history []*domain.HealthHistoryEntry
createErr error
getErr error
updateErr error
deleteErr error
listErr error
listDueErr error
getHistoryErr error
recordHistoryErr error
purgeHistoryErr error
getSummaryErr error
getSummaryResult *domain.HealthCheckSummary
checks map[string]*domain.EndpointHealthCheck
history []*domain.HealthHistoryEntry
createErr error
getErr error
updateErr error
deleteErr error
listErr error
listDueErr error
getHistoryErr error
recordHistoryErr error
purgeHistoryErr error
getSummaryErr error
getSummaryResult *domain.HealthCheckSummary
}
func newMockHealthCheckRepo() *mockHealthCheckRepo {
@@ -151,9 +151,9 @@ func TestHealthCheckService_Create_Success(t *testing.T) {
svc := NewHealthCheckService(repo, nil, logger, 10, 5*time.Second, 30*24*time.Hour, false)
check := &domain.EndpointHealthCheck{
Endpoint: "example.com:443",
Status: domain.HealthStatusUnknown,
Enabled: true,
Endpoint: "example.com:443",
Status: domain.HealthStatusUnknown,
Enabled: true,
CheckIntervalSecs: 300,
}
+1 -1
View File
@@ -1,12 +1,12 @@
package service
import (
"time"
"context"
"errors"
"fmt"
"log/slog"
"strings"
"time"
"github.com/shankar0123/certctl/internal/domain"
"github.com/shankar0123/certctl/internal/repository"
@@ -36,9 +36,9 @@ func mkRunningJob(id, agentID string) *domain.Job {
a := agentID
now := time.Now()
return &domain.Job{
ID: id,
AgentID: &a,
Status: domain.JobStatusRunning,
ID: id,
AgentID: &a,
Status: domain.JobStatusRunning,
CreatedAt: now.Add(-2 * time.Hour),
}
}
+3 -3
View File
@@ -871,8 +871,8 @@ func TestJobService_ReapTimedOutJobs_ContinuesOnIndividualUpdateFailure(t *testi
jobA.ID: jobA,
jobB.ID: jobB,
},
StatusUpdates: make(map[string]domain.JobStatus),
UpdateErrorByID: make(map[string]error),
StatusUpdates: make(map[string]domain.JobStatus),
UpdateErrorByID: make(map[string]error),
UpdateErrorByIDMu: sync.Mutex{},
}
// Make Update fail only for jobA
@@ -892,7 +892,7 @@ func TestJobService_ReapTimedOutJobs_ContinuesOnIndividualUpdateFailure(t *testi
jobAAfter := jobRepo.Jobs[jobA.ID]
jobBAfter := jobRepo.Jobs[jobB.ID]
if jobAAfter.Status != domain.JobStatusFailed || jobBAfter.Status != domain.JobStatusFailed {
t.Fatalf("expected both jobs status Failed (modified before Update), got A=%s B=%s",
t.Fatalf("expected both jobs status Failed (modified before Update), got A=%s B=%s",
jobAAfter.Status, jobBAfter.Status)
}
+2 -2
View File
@@ -377,8 +377,8 @@ func TestExpandCIDR_AllowsPrivateRanges(t *testing.T) {
cidr string
min int
}{
{"10/8 sample", "10.0.0.0/30", 2}, // 2 usable (after removing network/broadcast)
{"172.16/12 sample", "172.16.0.0/30", 2}, // 2 usable
{"10/8 sample", "10.0.0.0/30", 2}, // 2 usable (after removing network/broadcast)
{"172.16/12 sample", "172.16.0.0/30", 2}, // 2 usable
{"192.168/16 sample", "192.168.1.1/32", 1}, // Single IP
}
+10 -10
View File
@@ -43,16 +43,16 @@ import "sync/atomic"
// New labels MUST also be added to OCSPCounters.Snapshot AND to the
// Prometheus exposer in Phase 8.
type OCSPCounters struct {
requestGET atomic.Uint64
requestPOST atomic.Uint64
requestSuccess atomic.Uint64
requestInvalid atomic.Uint64
issuerNotFound atomic.Uint64
certNotFound atomic.Uint64
signingFailed atomic.Uint64
nonceEchoed atomic.Uint64
nonceMalformed atomic.Uint64
rateLimited atomic.Uint64
requestGET atomic.Uint64
requestPOST atomic.Uint64
requestSuccess atomic.Uint64
requestInvalid atomic.Uint64
issuerNotFound atomic.Uint64
certNotFound atomic.Uint64
signingFailed atomic.Uint64
nonceEchoed atomic.Uint64
nonceMalformed atomic.Uint64
rateLimited atomic.Uint64
}
// NewOCSPCounters constructs a zero-value counter table. The caller
+7 -9
View File
@@ -977,7 +977,7 @@ func TestCheckExpiringCertificates_ARI_ShouldRenewNow(t *testing.T) {
ID: "rp-standard", Name: "Standard", RenewalWindowDays: 30,
AutoRenew: true, MaxRetries: 3, RetryInterval: 300,
AlertThresholdsDays: []int{30, 14, 7, 0},
CreatedAt: time.Now(), UpdatedAt: time.Now(),
CreatedAt: time.Now(), UpdatedAt: time.Now(),
}
policyRepo.AddPolicy(policy)
@@ -1050,7 +1050,7 @@ func TestCheckExpiringCertificates_ARI_NotYet(t *testing.T) {
ID: "rp-standard", Name: "Standard", RenewalWindowDays: 30,
AutoRenew: true, MaxRetries: 3, RetryInterval: 300,
AlertThresholdsDays: []int{30, 14, 7, 0},
CreatedAt: time.Now(), UpdatedAt: time.Now(),
CreatedAt: time.Now(), UpdatedAt: time.Now(),
}
policyRepo.AddPolicy(policy)
@@ -1110,7 +1110,7 @@ func TestCheckExpiringCertificates_ARI_NilResult_FallsThrough(t *testing.T) {
ID: "rp-standard", Name: "Standard", RenewalWindowDays: 30,
AutoRenew: true, MaxRetries: 3, RetryInterval: 300,
AlertThresholdsDays: []int{30, 14, 7, 0},
CreatedAt: time.Now(), UpdatedAt: time.Now(),
CreatedAt: time.Now(), UpdatedAt: time.Now(),
}
policyRepo.AddPolicy(policy)
@@ -1178,7 +1178,7 @@ func TestCheckExpiringCertificates_ARI_Error_FallsThrough(t *testing.T) {
ID: "rp-standard", Name: "Standard", RenewalWindowDays: 30,
AutoRenew: true, MaxRetries: 3, RetryInterval: 300,
AlertThresholdsDays: []int{30, 14, 7, 0},
CreatedAt: time.Now(), UpdatedAt: time.Now(),
CreatedAt: time.Now(), UpdatedAt: time.Now(),
}
policyRepo.AddPolicy(policy)
@@ -1313,7 +1313,6 @@ func TestFailJob_SetsFailedStatus(t *testing.T) {
}
}
// --- CreateDeploymentJobs Tests ---
func TestCreateDeploymentJobs_PartialFailure(t *testing.T) {
@@ -1331,10 +1330,10 @@ func TestCreateDeploymentJobs_PartialFailure(t *testing.T) {
// Create certificate
cert := &domain.ManagedCertificate{
ID: "mc-partial",
ID: "mc-partial",
CommonName: "test.example.com",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
certRepo.AddCert(cert)
@@ -1383,5 +1382,4 @@ func TestCreateDeploymentJobs_PartialFailure(t *testing.T) {
}
}
// stringPtr is defined in notification_test.go
+5 -5
View File
@@ -13,11 +13,11 @@ import (
// RevocationSvc provides revocation-related business logic.
// It handles certificate revocation, revocation notifications, and issuer coordination.
type RevocationSvc struct {
certRepo repository.CertificateRepository
revocationRepo repository.RevocationRepository
auditService *AuditService
notificationSvc *NotificationService
issuerRegistry *IssuerRegistry
certRepo repository.CertificateRepository
revocationRepo repository.RevocationRepository
auditService *AuditService
notificationSvc *NotificationService
issuerRegistry *IssuerRegistry
// ocspCacheInvalidator — production hardening II Phase 2 load-
// bearing security wire. After a successful revocation, the
// service MUST invalidate the OCSP response cache for this
+76 -76
View File
@@ -48,31 +48,31 @@ func TestExpireShortLivedCertificates_Success(t *testing.T) {
// Create a short-lived profile (TTL < 1 hour = 3600 seconds)
shortLivedProfile := &domain.CertificateProfile{
ID: "prof-short",
Name: "Short-Lived",
MaxTTLSeconds: 300, // 5 minutes
AllowShortLived: true,
Enabled: true,
ID: "prof-short",
Name: "Short-Lived",
MaxTTLSeconds: 300, // 5 minutes
AllowShortLived: true,
Enabled: true,
AllowedKeyAlgorithms: domain.DefaultKeyAlgorithms(),
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
}
profileRepo.AddProfile(shortLivedProfile)
// Create an active certificate that has already expired
expiredCert := &domain.ManagedCertificate{
ID: "mc-expired-short",
Name: "Expired Short-Lived Cert",
CommonName: "short.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-short",
Status: domain.CertificateStatusActive,
ExpiresAt: now.Add(-5 * time.Minute), // Already expired
CreatedAt: now.Add(-15 * time.Minute),
UpdatedAt: now.Add(-5 * time.Minute),
Tags: make(map[string]string),
ID: "mc-expired-short",
Name: "Expired Short-Lived Cert",
CommonName: "short.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-short",
Status: domain.CertificateStatusActive,
ExpiresAt: now.Add(-5 * time.Minute), // Already expired
CreatedAt: now.Add(-15 * time.Minute),
UpdatedAt: now.Add(-5 * time.Minute),
Tags: make(map[string]string),
}
certRepo.AddCert(expiredCert)
@@ -218,31 +218,31 @@ func TestExpireShortLivedCertificates_PartialUpdateError(t *testing.T) {
// Create a short-lived profile
shortLivedProfile := &domain.CertificateProfile{
ID: "prof-short",
Name: "Short-Lived",
MaxTTLSeconds: 300,
AllowShortLived: true,
Enabled: true,
ID: "prof-short",
Name: "Short-Lived",
MaxTTLSeconds: 300,
AllowShortLived: true,
Enabled: true,
AllowedKeyAlgorithms: domain.DefaultKeyAlgorithms(),
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
}
profileRepo.AddProfile(shortLivedProfile)
// Create a certificate with a failing update
expiredCert := &domain.ManagedCertificate{
ID: "mc-expired-fail",
Name: "Expired Cert That Will Fail",
CommonName: "fail.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-short",
Status: domain.CertificateStatusActive,
ExpiresAt: now.Add(-5 * time.Minute),
CreatedAt: now.Add(-15 * time.Minute),
UpdatedAt: now.Add(-5 * time.Minute),
Tags: make(map[string]string),
ID: "mc-expired-fail",
Name: "Expired Cert That Will Fail",
CommonName: "fail.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-short",
Status: domain.CertificateStatusActive,
ExpiresAt: now.Add(-5 * time.Minute),
CreatedAt: now.Add(-15 * time.Minute),
UpdatedAt: now.Add(-5 * time.Minute),
Tags: make(map[string]string),
}
certRepo.AddCert(expiredCert)
@@ -275,31 +275,31 @@ func TestExpireShortLivedCertificates_AlreadyExpired(t *testing.T) {
// Create a short-lived profile
shortLivedProfile := &domain.CertificateProfile{
ID: "prof-short",
Name: "Short-Lived",
MaxTTLSeconds: 300,
AllowShortLived: true,
Enabled: true,
ID: "prof-short",
Name: "Short-Lived",
MaxTTLSeconds: 300,
AllowShortLived: true,
Enabled: true,
AllowedKeyAlgorithms: domain.DefaultKeyAlgorithms(),
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
}
profileRepo.AddProfile(shortLivedProfile)
// Create a certificate that's already in Expired status
alreadyExpiredCert := &domain.ManagedCertificate{
ID: "mc-already-expired",
Name: "Already Expired Cert",
CommonName: "already-expired.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-short",
Status: domain.CertificateStatusExpired, // Already expired
ExpiresAt: now.Add(-30 * time.Minute),
CreatedAt: now.Add(-45 * time.Minute),
UpdatedAt: now.Add(-10 * time.Minute),
Tags: make(map[string]string),
ID: "mc-already-expired",
Name: "Already Expired Cert",
CommonName: "already-expired.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-short",
Status: domain.CertificateStatusExpired, // Already expired
ExpiresAt: now.Add(-30 * time.Minute),
CreatedAt: now.Add(-45 * time.Minute),
UpdatedAt: now.Add(-10 * time.Minute),
Tags: make(map[string]string),
}
certRepo.AddCert(alreadyExpiredCert)
@@ -329,31 +329,31 @@ func TestExpireShortLivedCertificates_ProfileNotShortLived(t *testing.T) {
// Create a regular (not short-lived) profile with TTL > 1 hour
regularProfile := &domain.CertificateProfile{
ID: "prof-regular",
Name: "Regular",
MaxTTLSeconds: 86400, // 24 hours
AllowShortLived: false,
Enabled: true,
ID: "prof-regular",
Name: "Regular",
MaxTTLSeconds: 86400, // 24 hours
AllowShortLived: false,
Enabled: true,
AllowedKeyAlgorithms: domain.DefaultKeyAlgorithms(),
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
AllowedEKUs: domain.DefaultEKUs(),
CreatedAt: now,
UpdatedAt: now,
}
profileRepo.AddProfile(regularProfile)
// Create an expired certificate with the regular profile
expiredCert := &domain.ManagedCertificate{
ID: "mc-expired-regular",
Name: "Expired Regular Cert",
CommonName: "regular.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-regular",
Status: domain.CertificateStatusActive,
ExpiresAt: now.Add(-1 * time.Hour),
CreatedAt: now.Add(-25 * time.Hour),
UpdatedAt: now.Add(-1 * time.Hour),
Tags: make(map[string]string),
ID: "mc-expired-regular",
Name: "Expired Regular Cert",
CommonName: "regular.example.com",
SANs: []string{},
IssuerID: "iss-test",
CertificateProfileID: "prof-regular",
Status: domain.CertificateStatusActive,
ExpiresAt: now.Add(-1 * time.Hour),
CreatedAt: now.Add(-25 * time.Hour),
UpdatedAt: now.Add(-1 * time.Hour),
Tags: make(map[string]string),
}
certRepo.AddCert(expiredCert)
+10 -10
View File
@@ -22,16 +22,16 @@ var ErrAgentNotFound = errors.New("referenced agent does not exist")
// validTargetTypes is the set of allowed target types for validation.
var validTargetTypes = map[domain.TargetType]bool{
domain.TargetTypeNGINX: true,
domain.TargetTypeApache: true,
domain.TargetTypeHAProxy: true,
domain.TargetTypeF5: true,
domain.TargetTypeIIS: true,
domain.TargetTypeTraefik: true,
domain.TargetTypeCaddy: true,
domain.TargetTypeEnvoy: true,
domain.TargetTypePostfix: true,
domain.TargetTypeDovecot: true,
domain.TargetTypeNGINX: true,
domain.TargetTypeApache: true,
domain.TargetTypeHAProxy: true,
domain.TargetTypeF5: true,
domain.TargetTypeIIS: true,
domain.TargetTypeTraefik: true,
domain.TargetTypeCaddy: true,
domain.TargetTypeEnvoy: true,
domain.TargetTypePostfix: true,
domain.TargetTypeDovecot: true,
domain.TargetTypeSSH: true,
domain.TargetTypeWinCertStore: true,
domain.TargetTypeJavaKeystore: true,
+12 -12
View File
@@ -11,9 +11,9 @@ import (
// VerificationService handles recording and querying certificate deployment verification results.
type VerificationService struct {
jobRepo repository.JobRepository
auditService *AuditService
logger *slog.Logger
jobRepo repository.JobRepository
auditService *AuditService
logger *slog.Logger
}
// NewVerificationService creates a new verification service.
@@ -23,9 +23,9 @@ func NewVerificationService(
logger *slog.Logger,
) *VerificationService {
return &VerificationService{
jobRepo: jobRepo,
auditService: auditService,
logger: logger,
jobRepo: jobRepo,
auditService: auditService,
logger: logger,
}
}
@@ -76,11 +76,11 @@ func (s *VerificationService) RecordVerificationResult(ctx context.Context, resu
// Record audit event
auditEvent := "job_verification_success"
auditDetails := map[string]interface{}{
"job_id": result.JobID,
"target_id": result.TargetID,
"expected_fingerprint": result.ExpectedFingerprint,
"actual_fingerprint": result.ActualFingerprint,
"verified": result.Verified,
"job_id": result.JobID,
"target_id": result.TargetID,
"expected_fingerprint": result.ExpectedFingerprint,
"actual_fingerprint": result.ActualFingerprint,
"verified": result.Verified,
}
if result.Error != "" {
@@ -114,7 +114,7 @@ func (s *VerificationService) GetVerificationResult(ctx context.Context, jobID s
}
result := &domain.VerificationResult{
JobID: job.ID,
JobID: job.ID,
Verified: job.VerificationStatus == domain.VerificationSuccess,
}