ci: add golangci-lint config and fix formatting

- Add .golangci.yml with minimal linters (govet, ineffassign)
- Run gofmt -s and goimports on all files to fix formatting
- Disable fieldalignment and copylocks checks in govet
This commit is contained in:
2025-12-11 17:53:28 +01:00
parent 6b66ae5429
commit 914307ac8f
89 changed files with 1516 additions and 1618 deletions

View File

@@ -9,18 +9,18 @@ import (
// AuditEvent represents an auditable event
type AuditEvent struct {
Timestamp time.Time
User string
Action string
Resource string
Result string
Details map[string]interface{}
Timestamp time.Time
User string
Action string
Resource string
Result string
Details map[string]interface{}
}
// AuditLogger provides audit logging functionality
type AuditLogger struct {
log logger.Logger
enabled bool
log logger.Logger
enabled bool
}
// NewAuditLogger creates a new audit logger

View File

@@ -42,7 +42,7 @@ func VerifyChecksum(path string, expectedChecksum string) error {
func SaveChecksum(archivePath string, checksum string) error {
checksumPath := archivePath + ".sha256"
content := fmt.Sprintf("%s %s\n", checksum, archivePath)
if err := os.WriteFile(checksumPath, []byte(content), 0644); err != nil {
return fmt.Errorf("failed to save checksum: %w", err)
}
@@ -53,7 +53,7 @@ func SaveChecksum(archivePath string, checksum string) error {
// LoadChecksum loads checksum from a .sha256 file
func LoadChecksum(archivePath string) (string, error) {
checksumPath := archivePath + ".sha256"
data, err := os.ReadFile(checksumPath)
if err != nil {
return "", fmt.Errorf("failed to read checksum file: %w", err)

View File

@@ -49,7 +49,7 @@ func ValidateArchivePath(path string) (string, error) {
// Must have a valid archive extension
ext := strings.ToLower(filepath.Ext(cleaned))
validExtensions := []string{".dump", ".sql", ".gz", ".tar"}
valid := false
for _, validExt := range validExtensions {
if strings.HasSuffix(cleaned, validExt) {

View File

@@ -23,20 +23,20 @@ func NewPrivilegeChecker(log logger.Logger) *PrivilegeChecker {
// CheckAndWarn checks if running with elevated privileges and warns
func (pc *PrivilegeChecker) CheckAndWarn(allowRoot bool) error {
isRoot, user := pc.isRunningAsRoot()
if isRoot {
pc.log.Warn("⚠️ Running with elevated privileges (root/Administrator)")
pc.log.Warn("Security recommendation: Create a dedicated backup user with minimal privileges")
if !allowRoot {
return fmt.Errorf("running as root is not recommended, use --allow-root to override")
}
pc.log.Warn("Proceeding with root privileges (--allow-root specified)")
} else {
pc.log.Debug("Running as non-privileged user", "user", user)
}
return nil
}
@@ -52,7 +52,7 @@ func (pc *PrivilegeChecker) isRunningAsRoot() (bool, string) {
func (pc *PrivilegeChecker) isUnixRoot() (bool, string) {
uid := os.Getuid()
user := GetCurrentUser()
isRoot := uid == 0 || user == "root"
return isRoot, user
}
@@ -62,10 +62,10 @@ func (pc *PrivilegeChecker) isWindowsAdmin() (bool, string) {
// Check if running as Administrator on Windows
// This is a simplified check - full implementation would use Windows API
user := GetCurrentUser()
// Common admin user patterns on Windows
isAdmin := user == "Administrator" || user == "SYSTEM"
return isAdmin, user
}
@@ -89,11 +89,11 @@ func (pc *PrivilegeChecker) GetSecurityRecommendations() []string {
"Regularly rotate database passwords",
"Monitor audit logs for unauthorized access attempts",
}
if runtime.GOOS != "windows" {
recommendations = append(recommendations,
fmt.Sprintf("Run as non-root user: sudo -u %s dbbackup ...", pc.GetRecommendedUser()))
}
return recommendations
}

View File

@@ -1,4 +1,5 @@
// go:build !linux
//go:build !linux
// +build !linux
package security

View File

@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package security
@@ -19,7 +20,7 @@ func (rc *ResourceChecker) checkPlatformLimits() (*ResourceLimits, error) {
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit); err == nil {
limits.MaxOpenFiles = uint64(rLimit.Cur)
rc.log.Debug("Resource limit: max open files", "limit", rLimit.Cur, "max", rLimit.Max)
if rLimit.Cur < 1024 {
rc.log.Warn("⚠️ Low file descriptor limit detected",
"current", rLimit.Cur,

View File

@@ -1,3 +1,4 @@
//go:build windows
// +build windows
package security
@@ -23,5 +24,3 @@ func (rc *ResourceChecker) checkPlatformLimits() (*ResourceLimits, error) {
return limits, nil
}

View File

@@ -46,13 +46,13 @@ func (rp *RetentionPolicy) CleanupOldBackups(backupDir string) (int, int64, erro
}
if len(archives) <= rp.MinBackups {
rp.log.Debug("Keeping all backups (below minimum threshold)",
rp.log.Debug("Keeping all backups (below minimum threshold)",
"count", len(archives), "min_backups", rp.MinBackups)
return 0, 0, nil
}
cutoffTime := time.Now().AddDate(0, 0, -rp.RetentionDays)
// Sort by modification time (oldest first)
sort.Slice(archives, func(i, j int) bool {
return archives[i].ModTime.Before(archives[j].ModTime)
@@ -65,14 +65,14 @@ func (rp *RetentionPolicy) CleanupOldBackups(backupDir string) (int, int64, erro
// Keep minimum number of backups
remaining := len(archives) - i
if remaining <= rp.MinBackups {
rp.log.Debug("Stopped cleanup to maintain minimum backups",
rp.log.Debug("Stopped cleanup to maintain minimum backups",
"remaining", remaining, "min_backups", rp.MinBackups)
break
}
// Delete if older than retention period
if archive.ModTime.Before(cutoffTime) {
rp.log.Info("Removing old backup",
rp.log.Info("Removing old backup",
"file", filepath.Base(archive.Path),
"age_days", int(time.Since(archive.ModTime).Hours()/24),
"size_mb", archive.Size/1024/1024)
@@ -100,7 +100,7 @@ func (rp *RetentionPolicy) CleanupOldBackups(backupDir string) (int, int64, erro
}
if deletedCount > 0 {
rp.log.Info("Cleanup completed",
rp.log.Info("Cleanup completed",
"deleted_backups", deletedCount,
"freed_space_mb", freedSpace/1024/1024,
"retention_days", rp.RetentionDays)
@@ -124,7 +124,7 @@ func (rp *RetentionPolicy) scanBackupArchives(backupDir string) ([]ArchiveInfo,
}
name := entry.Name()
// Skip non-backup files
if !isBackupArchive(name) {
continue
@@ -161,7 +161,7 @@ func isBackupArchive(name string) bool {
// extractDatabaseName extracts database name from archive filename
func extractDatabaseName(filename string) string {
base := filepath.Base(filename)
// Remove extensions
for {
oldBase := base
@@ -170,7 +170,7 @@ func extractDatabaseName(filename string) string {
break
}
}
// Remove timestamp patterns
if len(base) > 20 {
// Typically: db_name_20240101_120000
@@ -184,7 +184,7 @@ func extractDatabaseName(filename string) string {
}
}
}
return base
}