style: run gofmt -s across all Go files

Fixes Go Report Card gofmt score from 52% to 100%.
Pure formatting changes — no logic modifications.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Shankar
2026-03-17 19:32:29 -04:00
parent 1349f2ef71
commit f1eff55894
28 changed files with 280 additions and 281 deletions
+2 -2
View File
@@ -12,8 +12,8 @@ import (
// MockJobService is a mock implementation of JobService interface. // MockJobService is a mock implementation of JobService interface.
type MockJobService struct { type MockJobService struct {
ListJobsFn func(status, jobType string, page, perPage int) ([]domain.Job, int64, error) ListJobsFn func(status, jobType string, page, perPage int) ([]domain.Job, int64, error)
GetJobFn func(id string) (*domain.Job, error) GetJobFn func(id string) (*domain.Job, error)
CancelJobFn func(id string) error CancelJobFn func(id string) error
} }
+1 -1
View File
@@ -126,7 +126,7 @@ func isValidHostnameChar(r rune) bool {
r == '.' || r == '.' ||
r == '-' || r == '-' ||
r == '_' || // Underscores are sometimes allowed r == '_' || // Underscores are sometimes allowed
r == '*' // Wildcard support r == '*' // Wildcard support
} }
// Error method makes ValidationError satisfy the error interface. // Error method makes ValidationError satisfy the error interface.
+6 -6
View File
@@ -37,9 +37,9 @@ type ServerConfig struct {
// DatabaseConfig contains database connection configuration. // DatabaseConfig contains database connection configuration.
type DatabaseConfig struct { type DatabaseConfig struct {
URL string URL string
MaxConnections int MaxConnections int
MigrationsPath string MigrationsPath string
} }
// SchedulerConfig contains scheduler timing configuration. // SchedulerConfig contains scheduler timing configuration.
@@ -64,9 +64,9 @@ type AuthConfig struct {
// RateLimitConfig contains rate limiting configuration. // RateLimitConfig contains rate limiting configuration.
type RateLimitConfig struct { type RateLimitConfig struct {
Enabled bool Enabled bool
RPS float64 // Requests per second RPS float64 // Requests per second
BurstSize int // Maximum burst size BurstSize int // Maximum burst size
} }
// CORSConfig contains CORS configuration. // CORSConfig contains CORS configuration.
+4 -4
View File
@@ -22,10 +22,10 @@ import (
// Config represents the ACME issuer connector configuration. // Config represents the ACME issuer connector configuration.
type Config struct { type Config struct {
DirectoryURL string `json:"directory_url"` // ACME directory URL (e.g., https://acme-staging-v02.api.letsencrypt.org/directory) DirectoryURL string `json:"directory_url"` // ACME directory URL (e.g., https://acme-staging-v02.api.letsencrypt.org/directory)
Email string `json:"email"` // Contact email for the ACME account Email string `json:"email"` // Contact email for the ACME account
EABKid string `json:"eab_kid,omitempty"` // External Account Binding Key ID (for some CAs) EABKid string `json:"eab_kid,omitempty"` // External Account Binding Key ID (for some CAs)
EABHmac string `json:"eab_hmac,omitempty"` // External Account Binding HMAC Key EABHmac string `json:"eab_hmac,omitempty"` // External Account Binding HMAC Key
HTTPPort int `json:"http_port,omitempty"` // Port for HTTP-01 challenge server (default: 80) HTTPPort int `json:"http_port,omitempty"` // Port for HTTP-01 challenge server (default: 80)
} }
+15 -15
View File
@@ -33,12 +33,12 @@ type IssuanceRequest struct {
// IssuanceResult contains the result of a successful certificate issuance. // IssuanceResult contains the result of a successful certificate issuance.
type IssuanceResult struct { type IssuanceResult struct {
CertPEM string `json:"cert_pem"` CertPEM string `json:"cert_pem"`
ChainPEM string `json:"chain_pem"` ChainPEM string `json:"chain_pem"`
Serial string `json:"serial"` Serial string `json:"serial"`
NotBefore time.Time `json:"not_before"` NotBefore time.Time `json:"not_before"`
NotAfter time.Time `json:"not_after"` NotAfter time.Time `json:"not_after"`
OrderID string `json:"order_id"` OrderID string `json:"order_id"`
} }
// RenewalRequest contains the parameters for renewing a certificate. // RenewalRequest contains the parameters for renewing a certificate.
@@ -57,13 +57,13 @@ type RevocationRequest struct {
// OrderStatus contains the status of a pending issuance or renewal order. // OrderStatus contains the status of a pending issuance or renewal order.
type OrderStatus struct { type OrderStatus struct {
OrderID string `json:"order_id"` OrderID string `json:"order_id"`
Status string `json:"status"` Status string `json:"status"`
Message *string `json:"message,omitempty"` Message *string `json:"message,omitempty"`
CertPEM *string `json:"cert_pem,omitempty"` CertPEM *string `json:"cert_pem,omitempty"`
ChainPEM *string `json:"chain_pem,omitempty"` ChainPEM *string `json:"chain_pem,omitempty"`
Serial *string `json:"serial,omitempty"` Serial *string `json:"serial,omitempty"`
NotBefore *time.Time `json:"not_before,omitempty"` NotBefore *time.Time `json:"not_before,omitempty"`
NotAfter *time.Time `json:"not_after,omitempty"` NotAfter *time.Time `json:"not_after,omitempty"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
+4 -4
View File
@@ -379,10 +379,10 @@ func (c *Connector) generateCertificate(csr *x509.CertificateRequest, additional
x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageClientAuth,
}, },
DNSNames: dnsNames, DNSNames: dnsNames,
EmailAddresses: emails, EmailAddresses: emails,
SubjectKeyId: hashPublicKey(csr.PublicKey), SubjectKeyId: hashPublicKey(csr.PublicKey),
AuthorityKeyId: c.caCert.SubjectKeyId, AuthorityKeyId: c.caCert.SubjectKeyId,
} }
// Add IP addresses if present // Add IP addresses if present
+8 -8
View File
@@ -20,14 +20,14 @@ type Connector interface {
// Alert represents a notification alert with urgency. // Alert represents a notification alert with urgency.
type Alert struct { type Alert struct {
ID string `json:"id"` ID string `json:"id"`
Type string `json:"type"` Type string `json:"type"`
Severity string `json:"severity"` Severity string `json:"severity"`
Subject string `json:"subject"` Subject string `json:"subject"`
Message string `json:"message"` Message string `json:"message"`
Recipient string `json:"recipient"` Recipient string `json:"recipient"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
} }
// Event represents a notification event with contextual information. // Event represents a notification event with contextual information.
@@ -89,14 +89,14 @@ func (c *Connector) SendAlert(ctx context.Context, alert notifier.Alert) error {
// Format payload // Format payload
payload := map[string]interface{}{ payload := map[string]interface{}{
"type": "alert", "type": "alert",
"alert_id": alert.ID, "alert_id": alert.ID,
"severity": alert.Severity, "severity": alert.Severity,
"subject": alert.Subject, "subject": alert.Subject,
"message": alert.Message, "message": alert.Message,
"recipient": alert.Recipient, "recipient": alert.Recipient,
"created_at": alert.CreatedAt, "created_at": alert.CreatedAt,
"metadata": alert.Metadata, "metadata": alert.Metadata,
} }
if err := c.postWebhook(ctx, payload); err != nil { if err := c.postWebhook(ctx, payload); err != nil {
+10 -10
View File
@@ -13,12 +13,12 @@ import (
// Config represents the F5 BIG-IP deployment target configuration. // Config represents the F5 BIG-IP deployment target configuration.
type Config struct { type Config struct {
Host string `json:"host"` // F5 BIG-IP hostname or IP Host string `json:"host"` // F5 BIG-IP hostname or IP
Port int `json:"port"` // F5 iControl REST API port (default 443) Port int `json:"port"` // F5 iControl REST API port (default 443)
Username string `json:"username"` // Administrative username Username string `json:"username"` // Administrative username
Password string `json:"password"` // Administrative password Password string `json:"password"` // Administrative password
Partition string `json:"partition"` // F5 partition name (e.g., "Common") Partition string `json:"partition"` // F5 partition name (e.g., "Common")
SSLProfile string `json:"ssl_profile"` // SSL profile name to update SSLProfile string `json:"ssl_profile"` // SSL profile name to update
} }
// Connector implements the target.Connector interface for F5 BIG-IP load balancers. // Connector implements the target.Connector interface for F5 BIG-IP load balancers.
@@ -138,10 +138,10 @@ func (c *Connector) DeployCertificate(ctx context.Context, request target.Deploy
Message: "Certificate deployment to F5 initiated (stub)", Message: "Certificate deployment to F5 initiated (stub)",
DeployedAt: time.Now(), DeployedAt: time.Now(),
Metadata: map[string]string{ Metadata: map[string]string{
"host": c.config.Host, "host": c.config.Host,
"partition": c.config.Partition, "partition": c.config.Partition,
"ssl_profile": c.config.SSLProfile, "ssl_profile": c.config.SSLProfile,
"duration_ms": fmt.Sprintf("%d", deploymentDuration.Milliseconds()), "duration_ms": fmt.Sprintf("%d", deploymentDuration.Milliseconds()),
}, },
}, nil }, nil
} }
+14 -14
View File
@@ -14,10 +14,10 @@ import (
// Config represents the IIS deployment target configuration. // Config represents the IIS deployment target configuration.
// This configuration is for Windows agents that manage IIS servers. // This configuration is for Windows agents that manage IIS servers.
type Config struct { type Config struct {
Hostname string `json:"hostname"` // Target hostname or IP Hostname string `json:"hostname"` // Target hostname or IP
SiteName string `json:"site_name"` // IIS site name (e.g., "Default Web Site") SiteName string `json:"site_name"` // IIS site name (e.g., "Default Web Site")
CertStore string `json:"cert_store"` // Windows cert store (e.g., "My", "WebHosting") CertStore string `json:"cert_store"` // Windows cert store (e.g., "My", "WebHosting")
BindingInfo string `json:"binding_info"` // Binding info (e.g., "*.example.com") BindingInfo string `json:"binding_info"` // Binding info (e.g., "*.example.com")
} }
// Connector implements the target.Connector interface for IIS (Internet Information Services). // Connector implements the target.Connector interface for IIS (Internet Information Services).
@@ -86,12 +86,12 @@ func (c *Connector) ValidateConfig(ctx context.Context, rawConfig json.RawMessag
// the IIS binding to use the new certificate. // the IIS binding to use the new certificate.
// //
// The IIS deployment process (via PowerShell): // The IIS deployment process (via PowerShell):
// 1. Create a temporary PFX file from the certificate and existing private key // 1. Create a temporary PFX file from the certificate and existing private key
// (Note: The private key is managed by the agent, not provided by the control plane) // (Note: The private key is managed by the agent, not provided by the control plane)
// 2. Import the PFX to the Windows certificate store (My store by default) // 2. Import the PFX to the Windows certificate store (My store by default)
// 3. Get the certificate thumbprint // 3. Get the certificate thumbprint
// 4. Update the IIS binding to use the new certificate by thumbprint // 4. Update the IIS binding to use the new certificate by thumbprint
// 5. Verify the binding is active // 5. Verify the binding is active
// //
// TODO: Implement actual PowerShell commands: // TODO: Implement actual PowerShell commands:
// - Import-PfxCertificate -FilePath {pfxPath} -CertStoreLocation "Cert:\LocalMachine\My" // - Import-PfxCertificate -FilePath {pfxPath} -CertStoreLocation "Cert:\LocalMachine\My"
@@ -128,10 +128,10 @@ func (c *Connector) DeployCertificate(ctx context.Context, request target.Deploy
Message: "Certificate deployment to IIS initiated (stub)", Message: "Certificate deployment to IIS initiated (stub)",
DeployedAt: time.Now(), DeployedAt: time.Now(),
Metadata: map[string]string{ Metadata: map[string]string{
"hostname": c.config.Hostname, "hostname": c.config.Hostname,
"site_name": c.config.SiteName, "site_name": c.config.SiteName,
"cert_store": c.config.CertStore, "cert_store": c.config.CertStore,
"duration_ms": fmt.Sprintf("%d", deploymentDuration.Milliseconds()), "duration_ms": fmt.Sprintf("%d", deploymentDuration.Milliseconds()),
}, },
}, nil }, nil
} }
+18 -18
View File
@@ -23,37 +23,37 @@ type Connector interface {
// In agent keygen mode, KeyPEM is populated from the agent's local key store. // In agent keygen mode, KeyPEM is populated from the agent's local key store.
// In server keygen mode (demo only), KeyPEM may be empty if the key was embedded in the cert version. // In server keygen mode (demo only), KeyPEM may be empty if the key was embedded in the cert version.
type DeploymentRequest struct { type DeploymentRequest struct {
CertPEM string `json:"cert_pem"` CertPEM string `json:"cert_pem"`
KeyPEM string `json:"key_pem,omitempty"` KeyPEM string `json:"key_pem,omitempty"`
ChainPEM string `json:"chain_pem"` ChainPEM string `json:"chain_pem"`
TargetConfig json.RawMessage `json:"target_config"` TargetConfig json.RawMessage `json:"target_config"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
} }
// DeploymentResult contains the result of a successful certificate deployment. // DeploymentResult contains the result of a successful certificate deployment.
type DeploymentResult struct { type DeploymentResult struct {
Success bool `json:"success"` Success bool `json:"success"`
TargetAddress string `json:"target_address"` TargetAddress string `json:"target_address"`
DeploymentID string `json:"deployment_id"` DeploymentID string `json:"deployment_id"`
Message string `json:"message"` Message string `json:"message"`
DeployedAt time.Time `json:"deployed_at"` DeployedAt time.Time `json:"deployed_at"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
} }
// ValidationRequest contains the parameters for validating a deployed certificate. // ValidationRequest contains the parameters for validating a deployed certificate.
type ValidationRequest struct { type ValidationRequest struct {
CertificateID string `json:"certificate_id"` CertificateID string `json:"certificate_id"`
Serial string `json:"serial"` Serial string `json:"serial"`
TargetConfig json.RawMessage `json:"target_config"` TargetConfig json.RawMessage `json:"target_config"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
} }
// ValidationResult contains the result of a certificate validation check. // ValidationResult contains the result of a certificate validation check.
type ValidationResult struct { type ValidationResult struct {
Valid bool `json:"valid"` Valid bool `json:"valid"`
Serial string `json:"serial"` Serial string `json:"serial"`
TargetAddress string `json:"target_address"` TargetAddress string `json:"target_address"`
Message string `json:"message"` Message string `json:"message"`
ValidatedAt time.Time `json:"validated_at"` ValidatedAt time.Time `json:"validated_at"`
Metadata map[string]string `json:"metadata,omitempty"` Metadata map[string]string `json:"metadata,omitempty"`
} }
+7 -7
View File
@@ -15,10 +15,10 @@ import (
// Config represents the NGINX deployment target configuration. // Config represents the NGINX deployment target configuration.
// This configuration is used on the agent side to deploy certificates to NGINX. // This configuration is used on the agent side to deploy certificates to NGINX.
type Config struct { type Config struct {
CertPath string `json:"cert_path"` // Path where cert will be written (typically /etc/nginx/certs/cert.pem) CertPath string `json:"cert_path"` // Path where cert will be written (typically /etc/nginx/certs/cert.pem)
KeyPath string `json:"key_path"` // Path where private key will be written (NOT provided by control plane) KeyPath string `json:"key_path"` // Path where private key will be written (NOT provided by control plane)
ChainPath string `json:"chain_path"` // Path where chain will be written (typically /etc/nginx/certs/chain.pem) ChainPath string `json:"chain_path"` // Path where chain will be written (typically /etc/nginx/certs/chain.pem)
ReloadCommand string `json:"reload_command"` // Command to reload NGINX (e.g., "nginx -s reload" or "systemctl reload nginx") ReloadCommand string `json:"reload_command"` // Command to reload NGINX (e.g., "nginx -s reload" or "systemctl reload nginx")
ValidateCommand string `json:"validate_command"` // Command to validate NGINX config (e.g., "nginx -t") ValidateCommand string `json:"validate_command"` // Command to validate NGINX config (e.g., "nginx -t")
} }
@@ -157,9 +157,9 @@ func (c *Connector) DeployCertificate(ctx context.Context, request target.Deploy
Message: "Certificate deployed and NGINX reloaded successfully", Message: "Certificate deployed and NGINX reloaded successfully",
DeployedAt: time.Now(), DeployedAt: time.Now(),
Metadata: map[string]string{ Metadata: map[string]string{
"cert_path": c.config.CertPath, "cert_path": c.config.CertPath,
"chain_path": c.config.ChainPath, "chain_path": c.config.ChainPath,
"duration_ms": fmt.Sprintf("%d", deploymentDuration.Milliseconds()), "duration_ms": fmt.Sprintf("%d", deploymentDuration.Milliseconds()),
}, },
}, nil }, nil
} }
+7 -7
View File
@@ -7,14 +7,14 @@ import (
// AuditEvent records an action taken in the control plane. // AuditEvent records an action taken in the control plane.
type AuditEvent struct { type AuditEvent struct {
ID string `json:"id"` ID string `json:"id"`
Actor string `json:"actor"` Actor string `json:"actor"`
ActorType ActorType `json:"actor_type"` ActorType ActorType `json:"actor_type"`
Action string `json:"action"` Action string `json:"action"`
ResourceType string `json:"resource_type"` ResourceType string `json:"resource_type"`
ResourceID string `json:"resource_id"` ResourceID string `json:"resource_id"`
Details json.RawMessage `json:"details"` Details json.RawMessage `json:"details"`
Timestamp time.Time `json:"timestamp"` Timestamp time.Time `json:"timestamp"`
} }
// ActorType represents the entity performing an action. // ActorType represents the entity performing an action.
+26 -26
View File
@@ -6,36 +6,36 @@ import (
// ManagedCertificate represents a certificate managed by the control plane. // ManagedCertificate represents a certificate managed by the control plane.
type ManagedCertificate struct { type ManagedCertificate struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
CommonName string `json:"common_name"` CommonName string `json:"common_name"`
SANs []string `json:"sans"` SANs []string `json:"sans"`
Environment string `json:"environment"` Environment string `json:"environment"`
OwnerID string `json:"owner_id"` OwnerID string `json:"owner_id"`
TeamID string `json:"team_id"` TeamID string `json:"team_id"`
IssuerID string `json:"issuer_id"` IssuerID string `json:"issuer_id"`
TargetIDs []string `json:"target_ids"` TargetIDs []string `json:"target_ids"`
RenewalPolicyID string `json:"renewal_policy_id"` RenewalPolicyID string `json:"renewal_policy_id"`
Status CertificateStatus `json:"status"` Status CertificateStatus `json:"status"`
ExpiresAt time.Time `json:"expires_at"` ExpiresAt time.Time `json:"expires_at"`
Tags map[string]string `json:"tags"` Tags map[string]string `json:"tags"`
LastRenewalAt *time.Time `json:"last_renewal_at,omitempty"` LastRenewalAt *time.Time `json:"last_renewal_at,omitempty"`
LastDeploymentAt *time.Time `json:"last_deployment_at,omitempty"` LastDeploymentAt *time.Time `json:"last_deployment_at,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
// CertificateVersion represents a specific version of a certificate. // CertificateVersion represents a specific version of a certificate.
type CertificateVersion struct { type CertificateVersion struct {
ID string `json:"id"` ID string `json:"id"`
CertificateID string `json:"certificate_id"` CertificateID string `json:"certificate_id"`
SerialNumber string `json:"serial_number"` SerialNumber string `json:"serial_number"`
NotBefore time.Time `json:"not_before"` NotBefore time.Time `json:"not_before"`
NotAfter time.Time `json:"not_after"` NotAfter time.Time `json:"not_after"`
FingerprintSHA256 string `json:"fingerprint_sha256"` FingerprintSHA256 string `json:"fingerprint_sha256"`
PEMChain string `json:"pem_chain"` PEMChain string `json:"pem_chain"`
CSRPEM string `json:"csr_pem"` CSRPEM string `json:"csr_pem"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
} }
// CertificateStatus represents the lifecycle status of a managed certificate. // CertificateStatus represents the lifecycle status of a managed certificate.
+16 -16
View File
@@ -18,25 +18,25 @@ type Issuer struct {
// DeploymentTarget represents a target system where certificates are deployed. // DeploymentTarget represents a target system where certificates are deployed.
type DeploymentTarget struct { type DeploymentTarget struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Type TargetType `json:"type"` Type TargetType `json:"type"`
AgentID string `json:"agent_id"` AgentID string `json:"agent_id"`
Config json.RawMessage `json:"config"` Config json.RawMessage `json:"config"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
// Agent represents an agent running on a target system. // Agent represents an agent running on a target system.
type Agent struct { type Agent struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Status AgentStatus `json:"status"` Status AgentStatus `json:"status"`
LastHeartbeatAt *time.Time `json:"last_heartbeat_at,omitempty"` LastHeartbeatAt *time.Time `json:"last_heartbeat_at,omitempty"`
RegisteredAt time.Time `json:"registered_at"` RegisteredAt time.Time `json:"registered_at"`
APIKeyHash string `json:"api_key_hash"` APIKeyHash string `json:"api_key_hash"`
} }
// AgentStatus represents the operational status of an agent. // AgentStatus represents the operational status of an agent.
@@ -52,7 +52,7 @@ const (
type IssuerType string type IssuerType string
const ( const (
IssuerTypeACME IssuerType = "ACME" IssuerTypeACME IssuerType = "ACME"
IssuerTypeGenericCA IssuerType = "GenericCA" IssuerTypeGenericCA IssuerType = "GenericCA"
) )
+15 -15
View File
@@ -7,18 +7,18 @@ import (
// Job represents a unit of work in the certificate control plane. // Job represents a unit of work in the certificate control plane.
type Job struct { type Job struct {
ID string `json:"id"` ID string `json:"id"`
Type JobType `json:"type"` Type JobType `json:"type"`
CertificateID string `json:"certificate_id"` CertificateID string `json:"certificate_id"`
TargetID *string `json:"target_id,omitempty"` TargetID *string `json:"target_id,omitempty"`
Status JobStatus `json:"status"` Status JobStatus `json:"status"`
Attempts int `json:"attempts"` Attempts int `json:"attempts"`
MaxAttempts int `json:"max_attempts"` MaxAttempts int `json:"max_attempts"`
LastError *string `json:"last_error,omitempty"` LastError *string `json:"last_error,omitempty"`
ScheduledAt time.Time `json:"scheduled_at"` ScheduledAt time.Time `json:"scheduled_at"`
StartedAt *time.Time `json:"started_at,omitempty"` StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"` CompletedAt *time.Time `json:"completed_at,omitempty"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
} }
// JobType represents the classification of work to be performed. // JobType represents the classification of work to be performed.
@@ -45,9 +45,9 @@ const (
// DeploymentJob represents a job that deploys a certificate to a target via an agent. // DeploymentJob represents a job that deploys a certificate to a target via an agent.
type DeploymentJob struct { type DeploymentJob struct {
Job `json:"job"` Job `json:"job"`
AgentID string `json:"agent_id"` AgentID string `json:"agent_id"`
DeploymentResult json.RawMessage `json:"deployment_result,omitempty"` DeploymentResult json.RawMessage `json:"deployment_result,omitempty"`
} }
// WorkItem enriches a Job with target details so the agent knows which connector to use. // WorkItem enriches a Job with target details so the agent knows which connector to use.
+12 -12
View File
@@ -7,13 +7,13 @@ import (
// PolicyRule defines enforcement rules for certificate management. // PolicyRule defines enforcement rules for certificate management.
type PolicyRule struct { type PolicyRule struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Type PolicyType `json:"type"` Type PolicyType `json:"type"`
Config json.RawMessage `json:"config"` Config json.RawMessage `json:"config"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }
// PolicyType represents the category of policy enforcement. // PolicyType represents the category of policy enforcement.
@@ -29,12 +29,12 @@ const (
// PolicyViolation records an instance of a certificate violating a policy rule. // PolicyViolation records an instance of a certificate violating a policy rule.
type PolicyViolation struct { type PolicyViolation struct {
ID string `json:"id"` ID string `json:"id"`
CertificateID string `json:"certificate_id"` CertificateID string `json:"certificate_id"`
RuleID string `json:"rule_id"` RuleID string `json:"rule_id"`
Message string `json:"message"` Message string `json:"message"`
Severity PolicySeverity `json:"severity"` Severity PolicySeverity `json:"severity"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
} }
// PolicySeverity indicates the impact level of a policy violation. // PolicySeverity indicates the impact level of a policy violation.
+2 -2
View File
@@ -910,8 +910,8 @@ func (m *mockIssuerRepository) Delete(ctx context.Context, id string) error {
// Mock service implementations for handlers that need them but aren't tested // Mock service implementations for handlers that need them but aren't tested
type mockTargetService struct { type mockTargetService struct {
targetRepo *mockTargetRepository targetRepo *mockTargetRepository
auditService *service.AuditService auditService *service.AuditService
} }
func (m *mockTargetService) ListTargets(page, perPage int) ([]domain.DeploymentTarget, int64, error) { func (m *mockTargetService) ListTargets(page, perPage int) ([]domain.DeploymentTarget, int64, error) {
+3 -3
View File
@@ -24,9 +24,9 @@ type JobFilter struct {
// AuditFilter defines filtering criteria for audit event queries. // AuditFilter defines filtering criteria for audit event queries.
type AuditFilter struct { type AuditFilter struct {
Actor string // username or service ID Actor string // username or service ID
ActorType string // "user", "agent", "system" ActorType string // "user", "agent", "system"
ResourceType string // e.g., "certificate", "policy", "agent" ResourceType string // e.g., "certificate", "policy", "agent"
ResourceID string ResourceID string
From time.Time From time.Time
To time.Time To time.Time
+3 -3
View File
@@ -19,9 +19,9 @@ type Scheduler struct {
logger *slog.Logger logger *slog.Logger
// Configurable tick intervals // Configurable tick intervals
renewalCheckInterval time.Duration renewalCheckInterval time.Duration
jobProcessorInterval time.Duration jobProcessorInterval time.Duration
agentHealthCheckInterval time.Duration agentHealthCheckInterval time.Duration
notificationProcessInterval time.Duration notificationProcessInterval time.Duration
} }
+8 -8
View File
@@ -14,13 +14,13 @@ import (
// AgentService provides business logic for managing and coordinating with agents. // AgentService provides business logic for managing and coordinating with agents.
type AgentService struct { type AgentService struct {
agentRepo repository.AgentRepository agentRepo repository.AgentRepository
certRepo repository.CertificateRepository certRepo repository.CertificateRepository
jobRepo repository.JobRepository jobRepo repository.JobRepository
targetRepo repository.TargetRepository targetRepo repository.TargetRepository
auditService *AuditService auditService *AuditService
issuerRegistry map[string]IssuerConnector issuerRegistry map[string]IssuerConnector
renewalService *RenewalService renewalService *RenewalService
} }
// NewAgentService creates a new agent service. // NewAgentService creates a new agent service.
@@ -161,7 +161,7 @@ func (s *AgentService) SubmitCSR(ctx context.Context, agentID string, certID str
} }
version := &domain.CertificateVersion{ version := &domain.CertificateVersion{
ID: generateID("certver"), ID: generateID("certver"),
CertificateID: certID, CertificateID: certID,
SerialNumber: result.Serial, SerialNumber: result.Serial,
NotBefore: result.NotBefore, NotBefore: result.NotBefore,
+2 -2
View File
@@ -11,7 +11,7 @@ import (
// CertificateService provides business logic for certificate management. // CertificateService provides business logic for certificate management.
type CertificateService struct { type CertificateService struct {
certRepo repository.CertificateRepository certRepo repository.CertificateRepository
policyService *PolicyService policyService *PolicyService
auditService *AuditService auditService *AuditService
} }
@@ -23,7 +23,7 @@ func NewCertificateService(
auditService *AuditService, auditService *AuditService,
) *CertificateService { ) *CertificateService {
return &CertificateService{ return &CertificateService{
certRepo: certRepo, certRepo: certRepo,
policyService: policyService, policyService: policyService,
auditService: auditService, auditService: auditService,
} }
+2 -2
View File
@@ -18,8 +18,8 @@ func TestCreateCertificate(t *testing.T) {
Events: []*domain.AuditEvent{}, Events: []*domain.AuditEvent{},
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: make(map[string]*domain.PolicyRule), Rules: make(map[string]*domain.PolicyRule),
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
policyService := NewPolicyService(policyRepo, NewAuditService(auditRepo)) policyService := NewPolicyService(policyRepo, NewAuditService(auditRepo))
+4 -5
View File
@@ -12,10 +12,10 @@ import (
// JobService manages job processing and status tracking. // JobService manages job processing and status tracking.
// It coordinates between the scheduler and various job-specific services. // It coordinates between the scheduler and various job-specific services.
type JobService struct { type JobService struct {
jobRepo repository.JobRepository jobRepo repository.JobRepository
renewalService *RenewalService renewalService *RenewalService
deploymentService *DeploymentService deploymentService *DeploymentService
logger *slog.Logger logger *slog.Logger
} }
// NewJobService creates a new job service. // NewJobService creates a new job service.
@@ -249,4 +249,3 @@ func (s *JobService) ListJobs(status, jobType string, page, perPage int) ([]doma
func (s *JobService) GetJob(id string) (*domain.Job, error) { func (s *JobService) GetJob(id string) (*domain.Job, error) {
return s.jobRepo.Get(context.Background(), id) return s.jobRepo.Get(context.Background(), id)
} }
+1 -1
View File
@@ -11,7 +11,7 @@ import (
// NotificationService provides business logic for managing notifications. // NotificationService provides business logic for managing notifications.
type NotificationService struct { type NotificationService struct {
notifRepo repository.NotificationRepository notifRepo repository.NotificationRepository
notifierRegistry map[string]Notifier notifierRegistry map[string]Notifier
} }
+23 -23
View File
@@ -12,8 +12,8 @@ import (
func TestCreateRule(t *testing.T) { func TestCreateRule(t *testing.T) {
ctx := context.Background() ctx := context.Background()
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: make(map[string]*domain.PolicyRule), Rules: make(map[string]*domain.PolicyRule),
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{Events: []*domain.AuditEvent{}} auditRepo := &mockAuditRepo{Events: []*domain.AuditEvent{}}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -58,8 +58,8 @@ func TestGetRule(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule}, Rules: map[string]*domain.PolicyRule{"rule-001": rule},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -79,8 +79,8 @@ func TestGetRule(t *testing.T) {
func TestGetRule_NotFound(t *testing.T) { func TestGetRule_NotFound(t *testing.T) {
ctx := context.Background() ctx := context.Background()
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: make(map[string]*domain.PolicyRule), Rules: make(map[string]*domain.PolicyRule),
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -115,8 +115,8 @@ func TestListRules(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule1, "rule-002": rule2}, Rules: map[string]*domain.PolicyRule{"rule-001": rule1, "rule-002": rule2},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -147,8 +147,8 @@ func TestUpdateRule(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": originalRule}, Rules: map[string]*domain.PolicyRule{"rule-001": originalRule},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{Events: []*domain.AuditEvent{}} auditRepo := &mockAuditRepo{Events: []*domain.AuditEvent{}}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -187,8 +187,8 @@ func TestDeleteRule(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule}, Rules: map[string]*domain.PolicyRule{"rule-001": rule},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{Events: []*domain.AuditEvent{}} auditRepo := &mockAuditRepo{Events: []*domain.AuditEvent{}}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -223,8 +223,8 @@ func TestValidateCertificate(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule}, Rules: map[string]*domain.PolicyRule{"rule-001": rule},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -265,8 +265,8 @@ func TestValidateCertificate_WithViolation(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule}, Rules: map[string]*domain.PolicyRule{"rule-001": rule},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -319,8 +319,8 @@ func TestValidateCertificate_MultipleViolations(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule1, "rule-002": rule2}, Rules: map[string]*domain.PolicyRule{"rule-001": rule1, "rule-002": rule2},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -330,7 +330,7 @@ func TestValidateCertificate_MultipleViolations(t *testing.T) {
cert := &domain.ManagedCertificate{ cert := &domain.ManagedCertificate{
ID: "cert-001", ID: "cert-001",
CommonName: "example.com", CommonName: "example.com",
IssuerID: "", // Missing issuer IssuerID: "", // Missing issuer
Tags: nil, // Missing metadata Tags: nil, // Missing metadata
Status: domain.CertificateStatusActive, Status: domain.CertificateStatusActive,
ExpiresAt: now.AddDate(1, 0, 0), ExpiresAt: now.AddDate(1, 0, 0),
@@ -368,8 +368,8 @@ func TestListPolicies(t *testing.T) {
} }
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: map[string]*domain.PolicyRule{"rule-001": rule1, "rule-002": rule2}, Rules: map[string]*domain.PolicyRule{"rule-001": rule1, "rule-002": rule2},
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
@@ -392,8 +392,8 @@ func TestListPolicies(t *testing.T) {
func TestCreatePolicy(t *testing.T) { func TestCreatePolicy(t *testing.T) {
now := time.Now() now := time.Now()
policyRepo := &mockPolicyRepo{ policyRepo := &mockPolicyRepo{
Rules: make(map[string]*domain.PolicyRule), Rules: make(map[string]*domain.PolicyRule),
Violations: []*domain.PolicyViolation{}, Violations: []*domain.PolicyViolation{},
} }
auditRepo := &mockAuditRepo{} auditRepo := &mockAuditRepo{}
auditService := NewAuditService(auditRepo) auditService := NewAuditService(auditRepo)
+15 -15
View File
@@ -204,7 +204,7 @@ func (s *RenewalService) sendThresholdAlerts(ctx context.Context, cert *domain.M
_ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem, _ = s.auditService.RecordEvent(ctx, "system", domain.ActorTypeSystem,
"expiration_alert_sent", "certificate", cert.ID, "expiration_alert_sent", "certificate", cert.ID,
map[string]interface{}{ map[string]interface{}{
"threshold_days": threshold, "threshold_days": threshold,
"days_until_expiry": daysUntil, "days_until_expiry": daysUntil,
}) })
} }
@@ -356,14 +356,14 @@ func (s *RenewalService) processRenewalServerKeygen(ctx context.Context, job *do
// Create new certificate version // Create new certificate version
version := &domain.CertificateVersion{ version := &domain.CertificateVersion{
ID: generateID("certver"), ID: generateID("certver"),
CertificateID: job.CertificateID, CertificateID: job.CertificateID,
SerialNumber: result.Serial, SerialNumber: result.Serial,
NotBefore: result.NotBefore, NotBefore: result.NotBefore,
NotAfter: result.NotAfter, NotAfter: result.NotAfter,
FingerprintSHA256: fingerprint, FingerprintSHA256: fingerprint,
PEMChain: result.CertPEM + "\n" + result.ChainPEM, PEMChain: result.CertPEM + "\n" + result.ChainPEM,
CSRPEM: privKeyPEM, // Server mode: stores private key for agent deployment CSRPEM: privKeyPEM, // Server mode: stores private key for agent deployment
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
if err := s.certRepo.CreateVersion(ctx, version); err != nil { if err := s.certRepo.CreateVersion(ctx, version); err != nil {
@@ -439,14 +439,14 @@ func (s *RenewalService) CompleteAgentCSRRenewal(ctx context.Context, job *domai
// Store cert version — CSRPEM holds the actual CSR (not the private key!) // Store cert version — CSRPEM holds the actual CSR (not the private key!)
version := &domain.CertificateVersion{ version := &domain.CertificateVersion{
ID: generateID("certver"), ID: generateID("certver"),
CertificateID: cert.ID, CertificateID: cert.ID,
SerialNumber: result.Serial, SerialNumber: result.Serial,
NotBefore: result.NotBefore, NotBefore: result.NotBefore,
NotAfter: result.NotAfter, NotAfter: result.NotAfter,
FingerprintSHA256: fingerprint, FingerprintSHA256: fingerprint,
PEMChain: result.CertPEM + "\n" + result.ChainPEM, PEMChain: result.CertPEM + "\n" + result.ChainPEM,
CSRPEM: csrPEM, // Agent mode: stores actual CSR, not private key CSRPEM: csrPEM, // Agent mode: stores actual CSR, not private key
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
if err := s.certRepo.CreateVersion(ctx, version); err != nil { if err := s.certRepo.CreateVersion(ctx, version); err != nil {
+45 -45
View File
@@ -13,16 +13,16 @@ var errNotFound = errors.New("not found")
// mockCertRepo is a test implementation of CertificateRepository // mockCertRepo is a test implementation of CertificateRepository
type mockCertRepo struct { type mockCertRepo struct {
Certs map[string]*domain.ManagedCertificate Certs map[string]*domain.ManagedCertificate
Versions map[string][]*domain.CertificateVersion Versions map[string][]*domain.CertificateVersion
CreateErr error CreateErr error
UpdateErr error UpdateErr error
GetErr error GetErr error
ListErr error ListErr error
ListVersionsErr error ListVersionsErr error
ListVersionsResult []*domain.CertificateVersion ListVersionsResult []*domain.CertificateVersion
CreateVersionErr error CreateVersionErr error
ArchiveErr error ArchiveErr error
} }
func (m *mockCertRepo) List(ctx context.Context, filter *repository.CertificateFilter) ([]*domain.ManagedCertificate, int, error) { func (m *mockCertRepo) List(ctx context.Context, filter *repository.CertificateFilter) ([]*domain.ManagedCertificate, int, error) {
@@ -109,15 +109,15 @@ func (m *mockCertRepo) AddCert(cert *domain.ManagedCertificate) {
// mockJobRepo is a test implementation of JobRepository // mockJobRepo is a test implementation of JobRepository
type mockJobRepo struct { type mockJobRepo struct {
Jobs map[string]*domain.Job Jobs map[string]*domain.Job
StatusUpdates map[string]domain.JobStatus StatusUpdates map[string]domain.JobStatus
CreateErr error CreateErr error
UpdateErr error UpdateErr error
UpdateStatusErr error UpdateStatusErr error
GetErr error GetErr error
ListErr error ListErr error
ListByStatusErr error ListByStatusErr error
DeleteErr error DeleteErr error
} }
func (m *mockJobRepo) List(ctx context.Context) ([]*domain.Job, error) { func (m *mockJobRepo) List(ctx context.Context) ([]*domain.Job, error) {
@@ -261,7 +261,7 @@ func (m *mockNotifRepo) AddNotification(notif *domain.NotificationEvent) {
// mockAuditRepo is a test implementation of AuditRepository // mockAuditRepo is a test implementation of AuditRepository
type mockAuditRepo struct { type mockAuditRepo struct {
Events []*domain.AuditEvent Events []*domain.AuditEvent
CreateErr error CreateErr error
ListErr error ListErr error
} }
@@ -309,15 +309,15 @@ func (m *mockAuditRepo) AddEvent(event *domain.AuditEvent) {
// mockPolicyRepo is a test implementation of PolicyRepository // mockPolicyRepo is a test implementation of PolicyRepository
type mockPolicyRepo struct { type mockPolicyRepo struct {
Rules map[string]*domain.PolicyRule Rules map[string]*domain.PolicyRule
Violations []*domain.PolicyViolation Violations []*domain.PolicyViolation
CreateRuleErr error CreateRuleErr error
UpdateRuleErr error UpdateRuleErr error
DeleteRuleErr error DeleteRuleErr error
GetRuleErr error GetRuleErr error
ListRulesErr error ListRulesErr error
CreateViolationErr error CreateViolationErr error
ListViolationsErr error ListViolationsErr error
} }
func (m *mockPolicyRepo) ListRules(ctx context.Context) ([]*domain.PolicyRule, error) { func (m *mockPolicyRepo) ListRules(ctx context.Context) ([]*domain.PolicyRule, error) {
@@ -420,13 +420,13 @@ func (m *mockRenewalPolicyRepo) AddPolicy(policy *domain.RenewalPolicy) {
// mockAgentRepo is a test implementation of AgentRepository // mockAgentRepo is a test implementation of AgentRepository
type mockAgentRepo struct { type mockAgentRepo struct {
Agents map[string]*domain.Agent Agents map[string]*domain.Agent
HeartbeatUpdates map[string]time.Time HeartbeatUpdates map[string]time.Time
CreateErr error CreateErr error
UpdateErr error UpdateErr error
DeleteErr error DeleteErr error
GetErr error GetErr error
ListErr error ListErr error
UpdateHeartbeatErr error UpdateHeartbeatErr error
GetByAPIKeyErr error GetByAPIKeyErr error
} }
@@ -509,13 +509,13 @@ func (m *mockAgentRepo) AddAgent(agent *domain.Agent) {
// mockTargetRepo is a test implementation of TargetRepository // mockTargetRepo is a test implementation of TargetRepository
type mockTargetRepo struct { type mockTargetRepo struct {
Targets map[string]*domain.DeploymentTarget Targets map[string]*domain.DeploymentTarget
CreateErr error CreateErr error
UpdateErr error UpdateErr error
DeleteErr error DeleteErr error
GetErr error GetErr error
ListErr error ListErr error
ListByCertErr error ListByCertErr error
} }
func (m *mockTargetRepo) List(ctx context.Context) ([]*domain.DeploymentTarget, error) { func (m *mockTargetRepo) List(ctx context.Context) ([]*domain.DeploymentTarget, error) {
@@ -667,9 +667,9 @@ func newMockIssuerRepository() *mockIssuerRepository {
// mockIssuerRepository is a test implementation of IssuerRepository // mockIssuerRepository is a test implementation of IssuerRepository
type mockIssuerRepository struct { type mockIssuerRepository struct {
issuers map[string]*domain.Issuer issuers map[string]*domain.Issuer
GetErr error GetErr error
ListErr error ListErr error
CreateErr error CreateErr error
UpdateErr error UpdateErr error
DeleteErr error DeleteErr error