fix(ethos): D-2 ETHOS compliance sweep
- Remove emoji from log statements across server and agent - Replace fmt.Printf with log.Printf in queries and handlers - Apply [TAG] [system] [component] format throughout - Exempt: display/terminal.go, setup.go, main.go CLI sections Total violations fixed: ~45 (emoji + fmt.Printf) All tests pass. Zero regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -476,7 +476,7 @@ func registerAgent(cfg *config.Config, serverURL string) error {
|
||||
log.Printf("Agent will not be able to verify update signatures")
|
||||
// Don't fail registration - key can be fetched later
|
||||
} else {
|
||||
log.Println("✓ Server public key cached successfully")
|
||||
log.Println("[INFO] [agent] [crypto] server_public_key_cached")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -491,11 +491,11 @@ func fetchAndCachePublicKey(serverURL string) error {
|
||||
// renewTokenIfNeeded handles 401 errors by renewing the agent token using refresh token
|
||||
func renewTokenIfNeeded(apiClient *client.Client, cfg *config.Config, err error) (*client.Client, error) {
|
||||
if err != nil && strings.Contains(err.Error(), "401 Unauthorized") {
|
||||
log.Printf("🔄 Access token expired - attempting renewal with refresh token...")
|
||||
log.Printf("[INFO] [agent] [auth] access_token_expired attempting_renewal")
|
||||
|
||||
// Check if we have a refresh token
|
||||
if cfg.RefreshToken == "" {
|
||||
log.Printf("❌ No refresh token available - re-registration required")
|
||||
log.Printf("[ERROR] [agent] [auth] no_refresh_token re-registration_required")
|
||||
return nil, fmt.Errorf("refresh token missing - please re-register agent")
|
||||
}
|
||||
|
||||
@@ -504,20 +504,20 @@ func renewTokenIfNeeded(apiClient *client.Client, cfg *config.Config, err error)
|
||||
|
||||
// Attempt to renew access token using refresh token
|
||||
if err := tempClient.RenewToken(cfg.AgentID, cfg.RefreshToken, version.Version); err != nil {
|
||||
log.Printf("❌ Refresh token renewal failed: %v", err)
|
||||
log.Printf("💡 Refresh token may be expired (>90 days) - re-registration required")
|
||||
log.Printf("[ERROR] [agent] [auth] refresh_token_renewal_failed error=%v", err)
|
||||
log.Printf("[INFO] [agent] [auth] refresh_token_may_be_expired re-registration_required")
|
||||
return nil, fmt.Errorf("refresh token renewal failed: %w - please re-register agent", err)
|
||||
}
|
||||
|
||||
// Update config with new access token (agent ID and refresh token stay the same!)
|
||||
// Update config with new access token
|
||||
cfg.Token = tempClient.GetToken()
|
||||
|
||||
// Save updated config
|
||||
if err := cfg.Save(constants.GetAgentConfigPath()); err != nil {
|
||||
log.Printf("⚠️ Warning: Failed to save renewed access token: %v", err)
|
||||
log.Printf("[WARNING] [agent] [auth] save_renewed_token_failed error=%v", err)
|
||||
}
|
||||
|
||||
log.Printf("✅ Access token renewed successfully - agent ID maintained: %s", cfg.AgentID)
|
||||
log.Printf("[INFO] [agent] [auth] access_token_renewed agent_id=%s", cfg.AgentID)
|
||||
return tempClient, nil
|
||||
}
|
||||
|
||||
@@ -841,7 +841,7 @@ func runAgent(cfg *config.Config) error {
|
||||
log.Printf("Failed to report system info: %v\n", err)
|
||||
} else {
|
||||
lastSystemInfoUpdate = time.Now()
|
||||
log.Printf("✓ System information updated\n")
|
||||
log.Printf("[INFO] [agent] [installer]System information updated\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1396,12 +1396,12 @@ func handleInstallUpdates(apiClient *client.Client, cfg *config.Config, ackTrack
|
||||
}
|
||||
|
||||
if result.Success {
|
||||
log.Printf("✓ Installation completed successfully in %d seconds\n", result.DurationSeconds)
|
||||
log.Printf("[INFO] [agent] [installer]Installation completed successfully in %d seconds\n", result.DurationSeconds)
|
||||
if len(result.PackagesInstalled) > 0 {
|
||||
log.Printf(" Packages installed: %v\n", result.PackagesInstalled)
|
||||
}
|
||||
} else {
|
||||
log.Printf("✗ Installation failed after %d seconds\n", result.DurationSeconds)
|
||||
log.Printf("[ERROR] [agent] [installer]Installation failed after %d seconds\n", result.DurationSeconds)
|
||||
log.Printf(" Error: %s\n", result.ErrorMessage)
|
||||
}
|
||||
|
||||
@@ -1510,14 +1510,14 @@ func handleDryRunUpdate(apiClient *client.Client, cfg *config.Config, ackTracker
|
||||
}
|
||||
|
||||
if result.Success {
|
||||
log.Printf("✓ Dry run completed successfully in %d seconds\n", result.DurationSeconds)
|
||||
log.Printf("[INFO] [agent] [installer]Dry run completed successfully in %d seconds\n", result.DurationSeconds)
|
||||
if len(result.Dependencies) > 0 {
|
||||
log.Printf(" Dependencies found: %v\n", result.Dependencies)
|
||||
} else {
|
||||
log.Printf(" No additional dependencies found\n")
|
||||
}
|
||||
} else {
|
||||
log.Printf("✗ Dry run failed after %d seconds\n", result.DurationSeconds)
|
||||
log.Printf("[ERROR] [agent] [installer]Dry run failed after %d seconds\n", result.DurationSeconds)
|
||||
log.Printf(" Error: %s\n", result.ErrorMessage)
|
||||
}
|
||||
|
||||
@@ -1623,12 +1623,12 @@ func handleConfirmDependencies(apiClient *client.Client, cfg *config.Config, ack
|
||||
}
|
||||
|
||||
if result.Success {
|
||||
log.Printf("✓ Installation with dependencies completed successfully in %d seconds\n", result.DurationSeconds)
|
||||
log.Printf("[INFO] [agent] [installer]Installation with dependencies completed successfully in %d seconds\n", result.DurationSeconds)
|
||||
if len(result.PackagesInstalled) > 0 {
|
||||
log.Printf(" Packages installed: %v\n", result.PackagesInstalled)
|
||||
}
|
||||
} else {
|
||||
log.Printf("✗ Installation with dependencies failed after %d seconds\n", result.DurationSeconds)
|
||||
log.Printf("[ERROR] [agent] [installer]Installation with dependencies failed after %d seconds\n", result.DurationSeconds)
|
||||
log.Printf(" Error: %s\n", result.ErrorMessage)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package main
|
||||
|
||||
// ethos_emoji_test.go — Pre-fix tests for emoji in agent main.go log statements.
|
||||
// D-2: main.go has emoji in token renewal and install result log paths.
|
||||
// EXCLUDES: registration CLI output (lines 294-322) and startup banner
|
||||
// (lines 691-697) which are intentional user-facing output.
|
||||
// ethos_emoji_test.go — Tests for emoji in agent main.go log statements.
|
||||
// D-2 FIXED: emoji removed from token renewal and install result log paths.
|
||||
// EXCLUDES: registration CLI output and startup banner (exempt).
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -20,34 +19,46 @@ func hasEmojiRune(s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// isExemptLine checks if a line number falls in an exempt range.
|
||||
// Exempt ranges are user-facing CLI output (registration, startup banner).
|
||||
func isExemptLine(lineNum int) bool {
|
||||
// Registration CLI output: ~lines 294-322
|
||||
if lineNum >= 290 && lineNum <= 330 {
|
||||
return true
|
||||
}
|
||||
// Startup banner: ~lines 691-700
|
||||
if lineNum >= 685 && lineNum <= 705 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestMainGoHasEmojiInLogStatements(t *testing.T) {
|
||||
// D-2: main.go has emoji in log statements for token renewal
|
||||
// and install results. These are NOT user-facing CLI output.
|
||||
// POST-FIX: No emoji in non-exempt log statements.
|
||||
content, err := os.ReadFile("agent/main.go")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read agent/main.go: %v", err)
|
||||
}
|
||||
|
||||
src := string(content)
|
||||
lines := strings.Split(src, "\n")
|
||||
lines := strings.Split(string(content), "\n")
|
||||
|
||||
// Count emoji in log.Printf lines only (not fmt.Printf CLI output)
|
||||
emojiLogCount := 0
|
||||
for _, line := range lines {
|
||||
for i, line := range lines {
|
||||
if isExemptLine(i + 1) {
|
||||
continue
|
||||
}
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if strings.Contains(trimmed, "log.Printf") && hasEmojiRune(trimmed) {
|
||||
emojiLogCount++
|
||||
}
|
||||
if strings.Contains(trimmed, "log.Println") && hasEmojiRune(trimmed) {
|
||||
isLog := strings.Contains(trimmed, "log.Printf") || strings.Contains(trimmed, "log.Println")
|
||||
if isLog && hasEmojiRune(trimmed) {
|
||||
emojiLogCount++
|
||||
}
|
||||
}
|
||||
|
||||
if emojiLogCount == 0 {
|
||||
t.Error("[ERROR] [agent] [main] D-2 already fixed: no emoji in main.go log statements")
|
||||
if emojiLogCount > 0 {
|
||||
t.Errorf("[ERROR] [agent] [main] D-2 NOT FIXED: %d non-exempt log statements with emoji", emojiLogCount)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [agent] [main] D-2 confirmed: %d log.Printf/Println with emoji in main.go", emojiLogCount)
|
||||
t.Log("[INFO] [agent] [main] D-2 FIXED: no emoji in non-exempt log statements")
|
||||
}
|
||||
|
||||
func TestMainGoLogStatementsHaveNoEmoji(t *testing.T) {
|
||||
@@ -56,14 +67,16 @@ func TestMainGoLogStatementsHaveNoEmoji(t *testing.T) {
|
||||
t.Fatalf("failed to read agent/main.go: %v", err)
|
||||
}
|
||||
|
||||
src := string(content)
|
||||
lines := strings.Split(src, "\n")
|
||||
lines := strings.Split(string(content), "\n")
|
||||
|
||||
for i, line := range lines {
|
||||
if isExemptLine(i + 1) {
|
||||
continue
|
||||
}
|
||||
trimmed := strings.TrimSpace(line)
|
||||
isLog := strings.Contains(trimmed, "log.Printf") || strings.Contains(trimmed, "log.Println")
|
||||
if isLog && hasEmojiRune(trimmed) {
|
||||
t.Errorf("[ERROR] [agent] [main] emoji in log at line %d", i+1)
|
||||
t.Errorf("[ERROR] [agent] [main] emoji in non-exempt log at line %d", i+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ func TestMigrationExecutorHasEmojiInOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if emojiCount == 0 {
|
||||
t.Error("[ERROR] [agent] [migration] D-2 already fixed: no emoji in executor.go")
|
||||
if emojiCount > 0 {
|
||||
t.Errorf("[ERROR] [agent] [migration] D-2 NOT FIXED: %d output lines with emoji", emojiCount)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [agent] [migration] D-2 confirmed: %d output lines with emoji in executor.go", emojiCount)
|
||||
t.Log("[INFO] [agent] [migration] D-2 FIXED: no emoji in executor.go")
|
||||
}
|
||||
|
||||
func TestMigrationExecutorHasNoEmojiInOutput(t *testing.T) {
|
||||
|
||||
@@ -340,7 +340,7 @@ func (e *MigrationExecutor) validateMigration() error {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("[MIGRATION] ✅ Migration validation successful\n")
|
||||
fmt.Printf("[INFO] [agent] [migration] validation_successful\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -501,9 +501,9 @@ func (e *MigrationExecutor) completeMigration(success bool, err error) (*Migrati
|
||||
}
|
||||
|
||||
if success {
|
||||
fmt.Printf("[MIGRATION] ✅ Migration completed successfully in %v\n", e.result.Duration)
|
||||
fmt.Printf("[INFO] [agent] [migration] completed duration=%v\n", e.result.Duration)
|
||||
if e.result.RollbackAvailable {
|
||||
fmt.Printf("[MIGRATION] 📦 Rollback available at: %s\n", e.result.BackupPath)
|
||||
fmt.Printf("[INFO] [agent] [migration] rollback_available path=%s\n", e.result.BackupPath)
|
||||
}
|
||||
|
||||
// Clean up old directories after successful migration
|
||||
@@ -511,7 +511,7 @@ func (e *MigrationExecutor) completeMigration(success bool, err error) (*Migrati
|
||||
fmt.Printf("[MIGRATION] Warning: Failed to cleanup old directories: %v\n", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("[MIGRATION] ❌ Migration failed after %v\n", e.result.Duration)
|
||||
fmt.Printf("[ERROR] [agent] [migration] failed duration=%v\n", e.result.Duration)
|
||||
if len(e.result.Errors) > 0 {
|
||||
for _, errMsg := range e.result.Errors {
|
||||
fmt.Printf("[MIGRATION] Error: %s\n", errMsg)
|
||||
|
||||
@@ -401,7 +401,7 @@ func (h *AgentUpdateHandler) BulkUpdateAgents(c *gin.Context) {
|
||||
log.Printf("Warning: Failed to log bulk agent update to system_events: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("✅ Bulk update initiated for %s: %s (%s)", agent.Hostname, req.Version, req.Platform)
|
||||
log.Printf("[INFO] [server] [updates]Bulk update initiated for %s: %s (%s)", agent.Hostname, req.Version, req.Platform)
|
||||
}
|
||||
|
||||
response := gin.H{
|
||||
@@ -492,7 +492,7 @@ func (h *AgentUpdateHandler) SignUpdatePackage(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("✅ Update package signed and saved: %s %s/%s (ID: %s)",
|
||||
log.Printf("[INFO] [server] [updates]Update package signed and saved: %s %s/%s (ID: %s)",
|
||||
pkg.Version, pkg.Platform, pkg.Architecture, pkg.ID)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
|
||||
@@ -314,10 +314,10 @@ func (h *AgentHandler) GetCommands(c *gin.Context) {
|
||||
if err == nil {
|
||||
// Log version check
|
||||
if updateAvailable {
|
||||
log.Printf("🔄 Agent %s (%s) version %s has update available: %s",
|
||||
log.Printf("[INFO] [server] [agents]Agent %s (%s) version %s has update available: %s",
|
||||
agent.Hostname, agentID, metrics.Version, h.latestAgentVersion)
|
||||
} else {
|
||||
log.Printf("✅ Agent %s (%s) version %s is up to date",
|
||||
log.Printf("[INFO] [server] [agents]Agent %s (%s) version %s is up to date",
|
||||
agent.Hostname, agentID, metrics.Version)
|
||||
}
|
||||
|
||||
@@ -439,10 +439,10 @@ func (h *AgentHandler) GetCommands(c *gin.Context) {
|
||||
} else {
|
||||
// Log version check for agent without version reporting
|
||||
if updateAvailable {
|
||||
log.Printf("🔄 Agent %s (%s) stored version %s has update available: %s",
|
||||
log.Printf("[INFO] [server] [agents]Agent %s (%s) stored version %s has update available: %s",
|
||||
agent.Hostname, agentID, agent.CurrentVersion, h.latestAgentVersion)
|
||||
} else {
|
||||
log.Printf("✅ Agent %s (%s) stored version %s is up to date",
|
||||
log.Printf("[INFO] [server] [agents]Agent %s (%s) stored version %s is up to date",
|
||||
agent.Hostname, agentID, agent.CurrentVersion)
|
||||
}
|
||||
}
|
||||
@@ -1118,7 +1118,7 @@ func (h *AgentHandler) RenewToken(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("✅ Token renewed successfully for agent %s (%s)", agent.Hostname, req.AgentID)
|
||||
log.Printf("[INFO] [server] [agents]Token renewed successfully for agent %s (%s)", agent.Hostname, req.AgentID)
|
||||
|
||||
// Return new access token
|
||||
response := models.TokenRenewalResponse{
|
||||
@@ -1300,7 +1300,7 @@ func (h *AgentHandler) ReportSystemInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("✅ System info updated for agent %s (%s): CPU=%s, Cores=%d, Memory=%dMB",
|
||||
log.Printf("[INFO] [server] [agents]System info updated for agent %s (%s): CPU=%s, Cores=%d, Memory=%dMB",
|
||||
agent.Hostname, agentID, req.CPUModel, req.CPUCores, req.MemoryTotal/1024/1024)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "system info updated successfully"})
|
||||
@@ -1328,19 +1328,19 @@ func (h *AgentHandler) EnableRapidPollingMode(agentID uuid.UUID, durationMinutes
|
||||
if currentUntil, err := time.Parse(time.RFC3339, untilStr); err == nil {
|
||||
// If current heartbeat expires later than the new duration, keep the longer duration
|
||||
if currentUntil.After(newRapidPollingUntil) {
|
||||
log.Printf("💓 Heartbeat already active for agent %s (%s), keeping longer duration (expires: %s)",
|
||||
log.Printf("[INFO] [server] [agents] heartbeatHeartbeat already active for agent %s (%s), keeping longer duration (expires: %s)",
|
||||
agent.Hostname, agentID, currentUntil.Format(time.RFC3339))
|
||||
return nil
|
||||
}
|
||||
// Otherwise extend the heartbeat
|
||||
log.Printf("💓 Extending heartbeat for agent %s (%s) from %s to %s",
|
||||
log.Printf("[INFO] [server] [agents] heartbeatExtending heartbeat for agent %s (%s) from %s to %s",
|
||||
agent.Hostname, agentID,
|
||||
currentUntil.Format(time.RFC3339),
|
||||
newRapidPollingUntil.Format(time.RFC3339))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("💓 Enabling heartbeat mode for agent %s (%s) for %d minutes",
|
||||
log.Printf("[INFO] [server] [agents] heartbeatEnabling heartbeat mode for agent %s (%s) for %d minutes",
|
||||
agent.Hostname, agentID, durationMinutes)
|
||||
}
|
||||
|
||||
@@ -1406,7 +1406,7 @@ func (h *AgentHandler) SetRapidPollingMode(c *gin.Context) {
|
||||
duration = req.DurationMinutes
|
||||
}
|
||||
|
||||
log.Printf("🚀 Rapid polling mode %s for agent %s (%s) for %d minutes",
|
||||
log.Printf("[INFO] [server] [agents]Rapid polling mode %s for agent %s (%s) for %d minutes",
|
||||
status, agent.Hostname, agentID, duration)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -94,7 +94,7 @@ func (h *DockerReportsHandler) ReportDockerImages(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := h.commandQueries.MarkCommandCompleted(commandID, result); err != nil {
|
||||
fmt.Printf("Warning: Failed to mark docker command %s as completed: %v\n", commandID, err)
|
||||
log.Printf("[WARNING] [server] [docker] mark_command_completed_failed command_id=%s error=%v", commandID, err)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
|
||||
@@ -41,11 +41,11 @@ func TestAgentsHandlerHasEmojiInLogs(t *testing.T) {
|
||||
t.Fatalf("failed to read agents.go: %v", err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
t.Error("[ERROR] [server] [handlers] D-2 already fixed: no emoji in agents.go logs")
|
||||
if count > 0 {
|
||||
t.Errorf("[ERROR] [server] [handlers] D-2 NOT FIXED: %d emoji log lines in agents.go", count)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [server] [handlers] D-2 confirmed: %d log statements with emoji in agents.go", count)
|
||||
t.Log("[INFO] [server] [handlers] D-2 FIXED: no emoji in agents.go logs")
|
||||
}
|
||||
|
||||
func TestAgentsHandlerHasNoEmojiInLogs(t *testing.T) {
|
||||
@@ -73,11 +73,11 @@ func TestUpdateHandlersHaveEmojiInLogs(t *testing.T) {
|
||||
total += count
|
||||
}
|
||||
|
||||
if total == 0 {
|
||||
t.Error("[ERROR] [server] [handlers] D-2 already fixed: no emoji in update handler logs")
|
||||
if total > 0 {
|
||||
t.Errorf("[ERROR] [server] [handlers] D-2 NOT FIXED: %d emoji log lines in update handlers", total)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [server] [handlers] D-2 confirmed: %d emoji log lines across update handlers", total)
|
||||
t.Log("[INFO] [server] [handlers] D-2 FIXED: no emoji in update handler logs")
|
||||
}
|
||||
|
||||
func TestUpdateHandlersHaveNoEmojiInLogs(t *testing.T) {
|
||||
|
||||
@@ -26,11 +26,11 @@ func TestHandlerFilesUseFmtPrintfForLogging(t *testing.T) {
|
||||
total += count
|
||||
}
|
||||
|
||||
if total == 0 {
|
||||
t.Error("[ERROR] [server] [handlers] D-2 already fixed: no fmt.Printf in handler logs")
|
||||
if total > 0 {
|
||||
t.Errorf("[ERROR] [server] [handlers] D-2 NOT FIXED: %d fmt.Printf in handler logs", total)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [server] [handlers] D-2 confirmed: %d fmt.Printf in docker_reports.go + metrics.go", total)
|
||||
t.Log("[INFO] [server] [handlers] D-2 FIXED: no fmt.Printf in handler logs")
|
||||
}
|
||||
|
||||
func TestHandlerFilesUseStructuredLogging(t *testing.T) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -93,7 +93,7 @@ func (h *MetricsHandler) ReportMetrics(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := h.commandQueries.MarkCommandCompleted(commandID, result); err != nil {
|
||||
fmt.Printf("Warning: Failed to mark metrics command %s as completed: %v\n", commandID, err)
|
||||
log.Printf("[WARNING] [server] [metrics] mark_command_completed_failed command_id=%s error=%v", commandID, err)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
|
||||
@@ -303,7 +303,7 @@ func (h *UnifiedUpdateHandler) ReportLog(c *gin.Context) {
|
||||
if err := h.updateQueries.UpdatePackageStatus(agentID, packageType, packageName, "updated", nil, completionTime); err != nil {
|
||||
log.Printf("Warning: Failed to update package status for %s/%s: %v", packageType, packageName, err)
|
||||
} else {
|
||||
log.Printf("✅ Package %s (%s) marked as updated after successful installation", packageName, packageType)
|
||||
log.Printf("[INFO] [server] [updates] package_updated package=%s type=%s", packageName, packageType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ func (h *UpdateHandler) ReportLog(c *gin.Context) {
|
||||
if err := h.updateQueries.UpdatePackageStatus(agentID, packageType, packageName, "updated", nil, completionTime); err != nil {
|
||||
log.Printf("Warning: Failed to update package status for %s/%s: %v", packageType, packageName, err)
|
||||
} else {
|
||||
log.Printf("✅ Package %s (%s) marked as updated after successful installation", packageName, packageType)
|
||||
log.Printf("[INFO] [server] [updates] package_updated package=%s type=%s", packageName, packageType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ func TestMachineBindingMiddlewareHasEmojiInLogs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if emojiLogCount == 0 {
|
||||
t.Error("[ERROR] [server] [middleware] D-2 already fixed: no emoji in machine_binding.go logs")
|
||||
if emojiLogCount > 0 {
|
||||
t.Errorf("[ERROR] [server] [middleware] D-2 NOT FIXED: %d emoji log lines remain", emojiLogCount)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [server] [middleware] D-2 confirmed: %d log statements with emoji in machine_binding.go", emojiLogCount)
|
||||
t.Log("[INFO] [server] [middleware] D-2 FIXED: no emoji in machine_binding.go logs")
|
||||
}
|
||||
|
||||
func TestMachineBindingMiddlewareHasNoEmojiInLogs(t *testing.T) {
|
||||
|
||||
@@ -147,7 +147,7 @@ func MachineBindingMiddleware(agentQueries *queries.AgentQueries, minAgentVersio
|
||||
}
|
||||
|
||||
if *agent.MachineID != reportedMachineID {
|
||||
log.Printf("[MachineBinding] ⚠️ SECURITY ALERT: Agent %s (%s) machine ID mismatch! DB=%s, Reported=%s",
|
||||
log.Printf("[WARNING] [server] [auth] machine_id_mismatch agent=%s (%s) db=%s reported=%s",
|
||||
agent.Hostname, agentID, *agent.MachineID, reportedMachineID)
|
||||
c.JSON(http.StatusForbidden, gin.H{
|
||||
"error": "machine ID mismatch - config file copied to different machine",
|
||||
@@ -159,7 +159,7 @@ func MachineBindingMiddleware(agentQueries *queries.AgentQueries, minAgentVersio
|
||||
}
|
||||
|
||||
// Machine ID validated - allow request
|
||||
log.Printf("[MachineBinding] ✓ Agent %s (%s) machine ID validated: %s",
|
||||
log.Printf("[INFO] [server] [auth] machine_id_validated agent=%s (%s) id=%s",
|
||||
agent.Hostname, agentID, reportedMachineID[:16]+"...")
|
||||
c.Next()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package queries
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/Fimeg/RedFlag/aggregator-server/internal/models"
|
||||
"github.com/google/uuid"
|
||||
@@ -59,7 +60,7 @@ func (q *DockerQueries) CreateDockerEventsBatch(events []models.StoredDockerImag
|
||||
)
|
||||
if err != nil {
|
||||
// Log error but continue with other events
|
||||
fmt.Printf("Warning: Failed to insert docker image event %s: %v\n", event.ID, err)
|
||||
log.Printf("[WARNING] [server] [database] docker_event_insert_failed event_id=%s error=%v", event.ID, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -312,7 +313,7 @@ func (q *DockerQueries) DeleteOldDockerImages(days int) error {
|
||||
}
|
||||
|
||||
if rowsAffected > 0 {
|
||||
fmt.Printf("Deleted %d old docker image records\n", rowsAffected)
|
||||
log.Printf("[INFO] [server] [database] docker_cleanup removed=%d", rowsAffected)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -26,11 +26,11 @@ func TestQueriesUseFmtPrintfForLogging(t *testing.T) {
|
||||
total += count
|
||||
}
|
||||
|
||||
if total == 0 {
|
||||
t.Error("[ERROR] [server] [database] D-2 already fixed: no fmt.Printf in query files")
|
||||
if total > 0 {
|
||||
t.Errorf("[ERROR] [server] [database] D-2 NOT FIXED: %d fmt.Printf calls in query files", total)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [server] [database] D-2 confirmed: %d fmt.Printf calls across query files", total)
|
||||
t.Log("[INFO] [server] [database] D-2 FIXED: no fmt.Printf in query files")
|
||||
}
|
||||
|
||||
func TestQueriesUseStructuredLogging(t *testing.T) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package queries
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/Fimeg/RedFlag/aggregator-server/internal/models"
|
||||
"github.com/google/uuid"
|
||||
@@ -59,7 +60,7 @@ func (q *MetricsQueries) CreateMetricsEventsBatch(events []models.StoredMetric)
|
||||
)
|
||||
if err != nil {
|
||||
// Log error but continue with other events
|
||||
fmt.Printf("Warning: Failed to insert metric event %s: %v\n", event.ID, err)
|
||||
log.Printf("[WARNING] [server] [database] metric_event_insert_failed event_id=%s error=%v", event.ID, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -278,7 +279,7 @@ func (q *MetricsQueries) DeleteOldMetrics(days int) error {
|
||||
}
|
||||
|
||||
if rowsAffected > 0 {
|
||||
fmt.Printf("Deleted %d old metric records\n", rowsAffected)
|
||||
log.Printf("[INFO] [server] [database] metrics_cleanup removed=%d", rowsAffected)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -3,6 +3,7 @@ package queries
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -371,7 +372,7 @@ func (q *UpdateQueries) CreateUpdateEventsBatch(events []models.UpdateEvent) err
|
||||
// Update current state
|
||||
if err := q.updateCurrentStateInTx(tx, &event); err != nil {
|
||||
// Log error but don't fail the entire batch
|
||||
fmt.Printf("Warning: failed to update current state for %s: %v\n", event.PackageName, err)
|
||||
log.Printf("[WARNING] [server] [database] update_state_failed package=%s error=%v", event.PackageName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -589,7 +590,7 @@ func (q *UpdateQueries) CleanupOldEvents(olderThan time.Duration) error {
|
||||
}
|
||||
|
||||
rowsAffected, _ := result.RowsAffected()
|
||||
fmt.Printf("Cleaned up %d old update events\n", rowsAffected)
|
||||
log.Printf("[INFO] [server] [database] update_events_cleanup removed=%d", rowsAffected)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@ func TestServicesUseFmtPrintfForLogging(t *testing.T) {
|
||||
}
|
||||
|
||||
count := strings.Count(string(content), "fmt.Printf")
|
||||
if count == 0 {
|
||||
t.Error("[ERROR] [server] [services] D-2 already fixed: no fmt.Printf in security_settings_service.go")
|
||||
if count > 0 {
|
||||
t.Errorf("[ERROR] [server] [services] D-2 NOT FIXED: %d fmt.Printf in security_settings_service.go", count)
|
||||
}
|
||||
|
||||
t.Logf("[INFO] [server] [services] D-2 confirmed: %d fmt.Printf calls in security_settings_service.go", count)
|
||||
t.Log("[INFO] [server] [services] D-2 FIXED: no fmt.Printf in security_settings_service.go")
|
||||
}
|
||||
|
||||
func TestServicesUseStructuredLogging(t *testing.T) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -134,7 +135,7 @@ func (s *SecuritySettingsService) SetSetting(category, key string, value interfa
|
||||
reason,
|
||||
); err != nil {
|
||||
// Log error but don't fail the operation
|
||||
fmt.Printf("Warning: failed to create audit log: %v\n", err)
|
||||
log.Printf("[WARNING] [server] [security] audit_log_create_failed error=%v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
45
docs/D2_Fix_Implementation.md
Normal file
45
docs/D2_Fix_Implementation.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# D-2 ETHOS Compliance Fix Implementation
|
||||
|
||||
**Date:** 2026-03-29
|
||||
**Branch:** culurien
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### Server — Emoji Removed
|
||||
| File | Violations Fixed |
|
||||
|------|-----------------|
|
||||
| `middleware/machine_binding.go` | 2 (security alert, validation) |
|
||||
| `handlers/agents.go` | 10 (version, token, heartbeat, rapid mode) |
|
||||
| `handlers/agent_updates.go` | 2 (bulk update, package signed) |
|
||||
| `handlers/update_handler.go` | 1 (package updated) |
|
||||
| `handlers/updates.go` | 1 (package updated) |
|
||||
|
||||
### Server — fmt.Printf Replaced
|
||||
| File | Violations Fixed |
|
||||
|------|-----------------|
|
||||
| `handlers/docker_reports.go` | 1 (command completion) |
|
||||
| `handlers/metrics.go` | 1 (command completion) |
|
||||
| `services/security_settings_service.go` | 1 (audit log) |
|
||||
| `queries/docker.go` | 2 (event insert, cleanup) |
|
||||
| `queries/metrics.go` | 2 (event insert, cleanup) |
|
||||
| `queries/updates.go` | 2 (state update, cleanup) |
|
||||
|
||||
### Agent — Emoji Removed
|
||||
| File | Violations Fixed |
|
||||
|------|-----------------|
|
||||
| `cmd/agent/main.go` | ~10 (key cache, token renewal, install results) |
|
||||
| `internal/migration/executor.go` | 4 (validation, completion, rollback, failure) |
|
||||
|
||||
## Exempt Files (NOT touched)
|
||||
- `display/terminal.go` — intentional terminal UI
|
||||
- `handlers/setup.go` — CLI wizard output
|
||||
- `cmd/agent/main.go` lines 294-322 — registration CLI output
|
||||
- `cmd/agent/main.go` lines 691-697 — startup banner
|
||||
|
||||
## Totals
|
||||
- Emoji violations fixed: ~36
|
||||
- fmt.Printf violations fixed: 9
|
||||
- **Total: ~45 violations fixed**
|
||||
- All tests pass. No regressions.
|
||||
Reference in New Issue
Block a user