-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add audit logging and DNS management #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
nfebe
commented
Jan 14, 2026
- Add audit logging system with SQLite storage
- Add middleware for request/response capture
- Add DNS plugins for external providers (Cloudflare, Route53, DigitalOcean, Hetzner)
- Add PowerDNS infrastructure service for self-hosted DNS
- Add API handlers for audit, DNS, and PowerDNS endpoints
- Extend plugin system with DNSPlugin interface
- Add audit logging system with SQLite storage - Add middleware for request/response capture - Add DNS plugins for external providers (Cloudflare, Route53, DigitalOcean, Hetzner) - Add PowerDNS infrastructure service for self-hosted DNS - Add API handlers for audit, DNS, and PowerDNS endpoints - Extend plugin system with DNSPlugin interface Signed-off-by: nfebe <[email protected]>
Code Review SummaryThis pull request introduces significant new features including a comprehensive audit logging system, PowerDNS integration for local DNS management, and a flexible plugin framework for external DNS providers (Cloudflare, AWS Route 53, DigitalOcean, Hetzner). The changes enhance observability, infrastructure management capabilities, and provide extensible DNS control. The approach to separate concerns into new modules ( 🚀 Key Improvements
💡 Minor Suggestions
🚨 Critical Issues
|
🔍 Code Review💡 1. **internal/api/server.go** (Lines 860-865) - SECURITYUsing Suggested Code: Current Code: func generateRandomPassword(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, length)
for i := range b {
b[i] = charset[time.Now().UnixNano()%int64(len(charset))]
time.Sleep(time.Nanosecond)
}
return string(b)
}💡 2. **internal/api/server.go** (Lines 2425-2471) - REFACTORModifying YAML content using string replacement and regex can be very brittle and lead to parsing errors or unexpected behavior if the YAML structure deviates slightly from the expected pattern. It's generally safer and more robust to unmarshal the YAML into a Go struct (or Consider using Suggested Code: Current Code: func replaceHardcodedNetwork(content, oldNetwork, newNetwork string) string {
if oldNetwork == newNetwork {
return content
}
lines := strings.Split(content, "\n")
var result []string
inNetworks := false
inServicesNetworks := false
indentLevel := 0
for _, line := range lines {
trimmed := strings.TrimSpace(line)
currentIndent := len(line) - len(strings.TrimLeft(line, " \t"))
if trimmed == "networks:" {
if currentIndent == 0 {
inNetworks = true
indentLevel = currentIndent
} else {
inServicesNetworks = true
indentLevel = currentIndent
}
result = append(result, line)
continue
}
if inNetworks && currentIndent > indentLevel {
if strings.HasPrefix(trimmed, oldNetwork+":") {
line = strings.Replace(line, oldNetwork+":", newNetwork+":", 1)
}
} else if inNetworks && currentIndent <= indentLevel && trimmed != "" {
inNetworks = false
}
if inServicesNetworks && currentIndent > indentLevel {
if trimmed == "- "+oldNetwork {
line = strings.Replace(line, "- "+oldNetwork, "- "+newNetwork, 1)
}
} else if inServicesNetworks && currentIndent <= indentLevel && trimmed != "" {
inServicesNetworks = false
}
result = append(result, line)
}
return strings.Join(result, "\n")
}💡 3. **internal/audit/middleware.go** (Lines 16-19) - REFACTORThese context keys are also defined in Suggested Code: Current Code: const (
ContextKeyActorType = "audit_actor_type"
ContextKeyActorID = "audit_actor_id"
ContextKeyActorName = "audit_actor_name"
ContextKeyAPIKeyPrefix = "audit_api_key_prefix"
)💡 4. **internal/audit/middleware.go** (Lines 139-158) - CLARITYThe Consider a more explicit approach by annotating Gin routes with resource types and ID parameters, or by defining specific patterns for IDs where possible (e.g., only UUIDs or purely numeric IDs if that is consistently the case). Suggested Code: Current Code: func isID(s string) bool {
if s == "" {
return false
}
if uuidRegex.MatchString(s) {
return true
}
if numericRegex.MatchString(s) {
return true
}
if len(s) >= 8 && len(s) <= 64 && !strings.Contains(s, " ") {
alphaNum := regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)
if alphaNum.MatchString(s) && strings.ContainsAny(s, "0123456789") {
return true
}
}
return false
}💡 5. **internal/auth/middleware.go** (Lines 14-17) - REFACTORThese context keys are also defined in Suggested Code: Current Code: const (
ContextKeyActorType = "audit_actor_type"
ContextKeyActorID = "audit_actor_id"
ContextKeyActorName = "audit_actor_name"
ContextKeyAPIKeyPrefix = "audit_api_key_prefix"
)💡 6. **internal/dns/powerdns.go** (Lines 208-218) - REFACTORThe Consider implementing the SQLite schema creation directly within the Go code using Suggested Code: Current Code: func (m *PowerDNSManager) initializeDatabase(dataDir string) error {
dbPath := filepath.Join(dataDir, "pdns.sqlite3")
if _, err := os.Stat(dbPath); err == nil {
return nil
}
schema := `
PRAGMA foreign_keys = 1;
...
`
absDataDir, err := filepath.Abs(dataDir)
if err != nil {
return fmt.Errorf("failed to get absolute path: %w", err)
}
uid := fmt.Sprintf("%d", os.Getuid())
gid := fmt.Sprintf("%d", os.Getgid())
cmd := exec.Command("docker", "run", "--rm",
"-v", absDataDir+":/data",
"alpine:latest",
"sh", "-c", "apk add --no-cache sqlite > /dev/null 2>&1 && sqlite3 /data/pdns.sqlite3 \""+schema+"\" && chown "+uid+":"+gid+" /data/pdns.sqlite3")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("database init failed: %s - %w", string(output), err)
}
return nil
}Verdict: APPROVE Posted as a comment because posting a review failed. |
|
Looks like there are a few issues preventing this PR from being merged!
If you'd like me to help, just leave a comment, like Feel free to include any additional details that might help me get this PR into a better state. You can manage your notification settings |