Documents
Codebase Metrics And Package Breakdown
Codebase Metrics And Package Breakdown
Type
Topic
Status
Published
Created
Mar 8, 2026
Updated
Apr 19, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Codebase Metrics And Package Breakdown#

The opnDossier project is a Go-based network analysis and documentation tool for OPNsense firewall configurations. As of January 2026, the codebase comprises 295 Go files (156 production, 139 test) organized into 20 internal packages across 12 logical domains and 4 public packages with no circular dependencies. The project received an overall architecture grade of A- (strong architecture with minor improvement opportunities) in a comprehensive architecture review conducted on January 14, 2026. Package counts updated as of PR #419 (March 2026).

The codebase demonstrates enterprise-grade software practices with 85% minimum test coverage enforced through CI/CD, 27 golden test files for snapshot testing, and 7 GitHub Actions workflows handling continuous integration, security scanning, documentation publishing, and automated releases. The architecture features a two-layer data model with 190 struct types split between XML DTOs (96 structs) and platform-agnostic domain models (94 structs), enabling clean separation between parsing logic and business domain representation.

Key architectural strengths include an exemplary plugin system with thread-safe registry patterns, security-first XML parsing with protection against XXE attacks and XML bombs, and modern Go idioms including proper error wrapping and context propagation. The project maintains comprehensive supply chain security through SLSA Level 3 provenance, Cosign keyless signing, and CycloneDX SBOM generation.

Codebase Statistics#

Code Volume#

Test Coverage#

Package Organization#

Internal Packages#

20 internal packages organized across 12 logical domains with no circular dependencies, clear boundaries between parsing, processing, conversion, and output:

  1. analysis/ - Shared detection, statistics, and rule comparison logic (10 files) - extracted from converter/enrichment.go and processor/analyze.go in PR #409 to eliminate code duplication; provides ComputeStatistics(), ComputeAnalysis(), DetectDeadRules(), DetectUnusedInterfaces(), DetectSecurityIssues(), DetectPerformanceIssues(), DetectConsistency(), and RulesEquivalent()
  2. audit/ - Compliance checking plugin system (8 files)
  3. cfgparser/ - XML parsing with security hardening (9 files)
  4. compliance/ - Plugin interfaces (3 files)
  5. config/ - Configuration management via Viper (7 files)
  6. constants/ - Shared constants and validation (2 files)
  7. converter/ - Multi-format export engine (50 files) - delegates statistics and analysis computation to internal/analysis/; builder.go split into builder_services.go and builder_vpn.go in PR #419 following the file-split refactoring pattern
  8. diff/ - Configuration diff engine (29 files)
  9. display/ - Terminal output with Lipgloss (7 files)
  10. docgen/ - Documentation generator (2 files)
  11. export/ - File export utilities (4 files)
  12. logging/ - Structured logging wrapper (2 files)
  13. markdown/ - Markdown generation (10 files)
  14. plugins/ - Built-in compliance plugins (7 files in 3 subdirs)
  15. pool/ - Buffer pooling (3 files)
  16. processor/ - Data processing and analysis (23 files) - delegates detection logic to internal/analysis/; report.go split into three focused files (report.go, report_statistics.go, report_markdown.go) in PR #415
  17. progress/ - Progress indicators (4 files)
  18. sanitizer/ - Sensitive data redaction (10 files)
  19. testing/ - Test utilities (2 files)
  20. validator/ - Configuration validation (7 files) - opnsense.go split into domain-specific modules (validate_network.go, validate_security.go, validate_system.go) in PR #417 for better code organization

Public Packages (pkg/)#

4 public packages comprising the importable API surface for external Go projects:

  1. model/ - Platform-agnostic CommonDevice domain model (15 files) - moved from internal/model/common/ in PR #404
  2. parser/ - Factory and DeviceParser interface (2 files) - renamed from ParserFactory, moved from internal/model/ in PR #404
  3. parser/opnsense/ - OPNsense parser implementation and schema-to-CommonDevice converter (13 files) - moved from internal/model/opnsense/ in PR #404
  4. schema/opnsense/ - OPNsense XML schema definitions (19 files) - moved from internal/schema/ in PR #404

These packages enable external consumers to parse OPNsense configurations and work with the CommonDevice model without depending on internal implementation details.

Top 10 Packages by File Count#

RankPackageProduction FilesTest FilesTotal Files
1internal/converter/~30~2050
2cmd/211233
3internal/diff/~17~1229
4internal/processor/~13~1023
5pkg/schema/opnsense/~13~619
6pkg/model/~10~515
7pkg/parser/opnsense/~8~513
8internal/sanitizer/~5~510
9internal/markdown/~6~410
10internal/cfgparser/~4~59

Struct Types and Data Models#

Total: 190 struct types across schema and model layers

pkg/schema/opnsense/ - 96 XML DTO structs#

Distribution across 13 files:

  • interfaces.go: 20 structs (Interface, VLAN, Bridge, GIF, GRE, LAGG, VIP, PPP, etc.)
  • security.go: 16 structs (Filter, NATRule, InboundRule, Rule, Firewall, IDS, IPsec, Swanctl)
  • services.go: 16 structs (DHCP, DNS, NTP, SNMP, LoadBalancer, Monit, Syslog)
  • system.go: 10 structs (System, WebGUIConfig, SSHConfig, User, Group, APIKey)
  • vpn.go: 10 structs (OpenVPN, WireGuard server/client configurations)
  • network.go: 8 structs (Gateways, StaticRoutes, DHCP options)
  • dhcp.go: 5 structs (Dhcpd, DhcpdInterface, DHCPStaticLease, Range)
  • opnsense.go: 3 structs (OpnSenseDocument, OPNsense, Cert)
  • Other files: 8 structs

pkg/model/ - 94 platform-agnostic structs#

Distribution across 14 files:

  • services.go: 26 structs (536 lines - largest file in pkg/model/)
  • enrichment.go: 21 structs (Statistics, Analysis, SecurityAssessment, ComplianceResults, ComplianceFinding, PluginComplianceResult, CompliancePluginInfo, ComplianceControl, ComplianceResultSummary, ComplianceAttackSurface, and others) - significantly expanded compliance data model
  • vpn.go: 10 structs (OpenVPN, WireGuard, IPsec configurations)
  • network.go: 9 structs (Interface, VLAN, Bridge, PPP, GIF, GRE, LAGG, VirtualIP, InterfaceGroup)
  • system.go: 7 structs (System, WebGUI, SSH, TrustConfig, Firmware, Bogons, SysctlItem)
  • firewall.go: 6 structs (FirewallRule, NATConfig, NATRule, InboundNATRule, NATSummary)
  • routing.go: 4 structs (Routing, Gateway, GatewayGroup, StaticRoute)
  • users.go: 3 structs (User, Group, APIKey)
  • device.go: 1 struct (CommonDevice - root platform-agnostic model)
  • Other files: 7 structs

Two-Layer Data Model Architecture#

The separation between XML DTOs (pkg/schema/opnsense/) and platform-agnostic domain types (pkg/model/) enables clean XML unmarshaling while providing a unified interface for all downstream consumers. The parser factory and OPNsense-specific converter live in pkg/parser/ and pkg/parser/opnsense/, forming a public API for external Go projects to parse OPNsense configurations.

CLI Metrics (cmd/ Directory)#

Commands Implemented#

Based on file structure, the CLI provides these commands:

  1. convert - Multi-format configuration export (main command)
  2. audit - Compliance checking with plugin system
  3. diff - Configuration comparison
  4. display - Interactive terminal display
  5. validate - Configuration validation
  6. sanitize - Sensitive data redaction
  7. config - Configuration management (init, show, validate subcommands)
  8. completion - Shell completion generation
  9. help - Enhanced help system with suggestions
  10. man - Man page generation

CI/CD Workflows#

7 GitHub Actions workflows handling CI, security, documentation, benchmarks, and releases:

1. CI Workflow (ci.yml)#

Triggers: Push to main, pull requests

Jobs (all depend on Lint passing first):

  1. Lint - golangci-lint v2.9 for code quality
  2. Test - Multi-platform matrix (ubuntu, macos, windows)
  3. Integration Tests - E2E with 5-minute timeout
  4. Coverage - Codecov upload, 85% threshold
  5. Build - Cross-compilation (FreeBSD, Linux, macOS, Windows)
  6. SBOM - CycloneDX binary and module SBOMs

Merge Requirements: 7 required checks enforced by Mergify (Lint, Build, Test×3 platforms, Integration Tests, Coverage)

2. Benchmarks Workflow (benchmarks.yml)#

Triggers: Push to main, PRs affecting Go files

Jobs:

  1. Benchmark - Focused benchmarks on converter, pool, log, cmd packages
  2. Startup Time Check - CLI startup performance verification

3. Release Workflow (release.yml)#

Triggers: Git tags matching "v*", manual dispatch

Sequential Pipeline:

  1. goreleaser - Multi-platform builds with GoReleaser v2
  2. provenance - SLSA Level 3 attestations
  3. verify - Automated signature and checksum verification

Artifacts: Binaries for 4 OSes (amd64/arm64), native packages (.deb, .rpm, .apk, .pkg.tar.xz), Docker images, SBOMs, Sigstore bundles

4. SBOM Workflow (sbom.yml)#

Triggers: Weekly cron (Sunday midnight UTC), manual dispatch

Steps: Build binary, generate binary SBOM, generate module SBOM (CycloneDX), upload with 90-day retention

5. OSSF Scorecard Workflow (scorecard.yml)#

Triggers: Branch protection changes, weekly cron (Saturday 8:32 AM UTC), push to main, manual

Steps: Run OSSF Scorecard v2.4.3, publish to OpenSSF REST API, upload SARIF to GitHub Code Scanning

6. Documentation Workflow (docs.yml)#

Triggers: Push to main

Pipeline: build (MkDocs) → deploy (GitHub Pages)

7. Copilot Setup Workflow (copilot-setup-steps.yml)#

Triggers: Manual dispatch, workflow file changes

Purpose: Validates GitHub Copilot setup instructions by installing mise toolchain, goimports, and project dependencies

Dependencies#

Testing Infrastructure#

Test Organization#

Testing Standards#

Per AGENTS.md:

  • Coverage Target: >80% (project enforces 85% standard)
  • Speed: <100ms per test
  • Race detection: Mandatory in CI via go test -race
  • Integration tests: Use build tags
  • Table-driven tests: Use subtests with t.Run() and t.Parallel()

Coverage Commands#

From justfile:

  • just test-coverage - Generate coverage report
  • just coverage - Open coverage in browser
  • just test-race - Run with race detection

Code Quality and Linting#

Security Linters: gosec detects security vulnerabilities, errcheck catches unchecked errors

Documentation Standards: godot enforces comment punctuation, revive enforces formatting rules, all exported packages require GoDoc comments

Architectural Strengths#

Plugin Architecture#

Finding and Compliance Result Structures#

  • Finding struct (defined in internal/analysis package) includes Severity field (string) as the canonical field for severity levels ("critical", "high", "medium", "low"); Type field contains the finding category (e.g., "compliance"), not the severity
  • Plugins derive severity from control metadata using controlSeverity() helper methods that reference Control.Severity as the single source of truth
  • ComplianceResults (defined in pkg/model) is the main compliance audit result container containing per-plugin findings, controls, and summary statistics; replaces the previous stub ComplianceChecks structure
  • ComplianceFinding represents individual compliance findings with fields for severity, title, description, recommendation, component, references, and optional attack surface information
  • PluginComplianceResult contains per-plugin compliance results including plugin metadata, findings, summary, controls, and compliance status map
  • ComplianceResultSummary tracks severity breakdowns with dedicated fields: TotalFindings, CriticalFindings, HighFindings, MediumFindings, LowFindings, InfoFindings, PluginCount, Compliant, NonCompliant (all int); these counts are properly calculated from Finding.Severity values
  • ComplianceControl represents individual control definitions with ID, title, description, category, severity, rationale, remediation, references, tags, and metadata
  • CompliancePluginInfo contains plugin metadata (name, version, description)
  • ComplianceAttackSurface represents attack surface information for red team findings with type, ports, services, and vulnerabilities
  • CommonDevice.ComplianceResults field type changed from *ComplianceChecks to *ComplianceResults - a rich nested structure containing full audit results across all plugins
  • Report structure uses TotalFindingsCount() method to aggregate findings across security and compliance results; blue team reports include per-plugin sections with individual severity breakdowns
  • Deep cloning of controls via CloneControls() ensures plugin consumers cannot mutate internal state

Security-First Parser Design#

Modern Go Patterns#

Technical Debt#

1. Global State (Moderate Concern)#

cmd/root.go contains global variables (cfgFile, Cfg, logger), internal/audit/plugin.go has GlobalRegistry

Mitigation: Plugin registry uses sync.RWMutex for thread safety, CLI globals follow Cobra conventions, CommandContext pattern implemented for dependency injection

2. Context Underutilization (Low-Medium Priority)#

Many functions accept context.Context but don't use it for cancellation, leaving them named as _. Long-running operations (analyzeDeadRules, analyzeInterfaceRules with O(n²) complexity, analyzeUnusedInterfaces, analyzeSecurityIssues) cannot be cancelled

3. Sequential Plugin Execution (Performance Optimization)#

Plugin checks run sequentially despite thread-safe registry enabling future parallelization. Worker pool implementation available in internal/processor/concurrent.go demonstrating context-aware concurrent patterns

4. Converter Pattern Fragmentation (Medium Priority)#

Two redundant markdown generation approaches exist: converter/markdown.go for legacy direct conversion (tests only) and converter/hybrid_generator.go for modern programmatic generation (production)

Recommended Consolidation: Create unified converter interface, delegate markdown generation to markdown package, document deprecation timeline

Supply Chain Security#

Development Workflow#

Development Commands via just#

  • just test - Run tests with coverage
  • just lint - Run linters
  • just check - Run all pre-commit checks
  • just ci-check - Full CI validation locally
  • just scan - Vulnerability scanning (gosec)
  • just sbom - Generate SBOM artifacts
  • just security-all - All security checks

Architecture Review Roadmap#

  • Follow-up Review: Q2 2026 after converter consolidation
  • High Priority: Consolidate converter pattern (Q2 2026 target) - Medium effort, high impact
  • Medium Priority: Improve context usage in long-running operations - Low effort, medium impact

Summary#

The opnDossier project demonstrates mature software architecture with an A- grade, reflecting strong architectural foundations with minor improvement opportunities identified. With 295 Go files organized into 20 internal packages, 4 public packages, and 190 struct types across two architectural layers, the codebase exhibits strong separation of concerns, an extensible plugin system, secure-by-default XML parsing, comprehensive testing infrastructure, and modern Go idioms. The enforced 85% test coverage threshold, 7 CI/CD workflows providing multi-platform testing and security scanning, and comprehensive supply chain security measures (SLSA Level 3, Cosign signing, SBOM generation) demonstrate enterprise-grade software engineering practices. No major architectural changes are required - the codebase is well-designed for long-term maintainability, with identified technical debt items representing opportunities for incremental improvement rather than fundamental architectural issues.

PR #373 enhanced the audit reporting system by fixing severity breakdown calculation and adding per-plugin severity reporting, ensuring audit reports properly display critical/high/medium/low finding counts.

PR #391 introduced the internal/analysis package with canonical Finding and Severity types, unifying finding representations across audit, compliance, and processor packages to eliminate duplication and improve consistency.

PR #400 moved audit report rendering from cmd/audit_handler.go to the internal/converter/builder layer, replaced the stub ComplianceChecks model with a rich ComplianceResults structure containing 7 new struct types (ComplianceResults, ComplianceFinding, PluginComplianceResult, CompliancePluginInfo, ComplianceControl, ComplianceResultSummary, ComplianceAttackSurface), and added BuildAuditSection()/WriteAuditSection() methods to enable format-agnostic compliance report generation across markdown, JSON, and YAML outputs. This architectural refactoring significantly expanded the compliance data model from 3 stub fields to a comprehensive nested structure capable of representing per-plugin findings, controls, and severity breakdowns.

PR #404 exposed the CommonDevice model, OPNsense parser, and schema definitions as public packages by moving them from internal/ to pkg/, enabling external Go projects to import and use the opnDossier parsing and data model capabilities. The parser factory was renamed from ParserFactory to Factory (following Go naming conventions), and the entire internal/model/ re-export shim layer (~90 type aliases) was removed. This establishes a clean public API surface with pkg/ packages that never import internal/ packages.

PR #409 extracted shared detection, statistics, and rule comparison logic from internal/converter/enrichment.go and internal/processor/analyze.go into a dedicated internal/analysis/ package (10 files: detect.go, statistics.go, rules.go, helpers.go, finding.go, and their corresponding test files). This refactoring eliminated code duplication between converter and processor packages, with both now delegating to analysis.ComputeStatistics(), analysis.ComputeAnalysis(), analysis.DetectDeadRules(), analysis.DetectUnusedInterfaces(), analysis.DetectSecurityIssues(), analysis.DetectPerformanceIssues(), analysis.DetectConsistency(), and analysis.RulesEquivalent(). The PR achieved 97.1% test coverage on the new package and added structured Kind fields to DeadRuleFinding for classification, improved gateway validation using net.ParseIP, and added nil guards to all exported functions for defensive API safety.

PR #415 split internal/processor/report.go (820 lines) into three focused files to comply with the project's 400-line guideline: report.go (256 lines, types/constructors/accessors/JSON/YAML serialization), report_statistics.go (218 lines, statistics computation and translation), and report_markdown.go (368 lines, markdown rendering). This mechanical refactor required no logic changes, no API changes, and no test modifications, adding only documentation comments.

PR #417 split internal/validator/opnsense.go (1,059 lines) into four domain-specific files for better code organization: opnsense.go (28 lines, main entry point and helper functions), validate_network.go (259 lines, network and DHCP validation), validate_security.go (255 lines, firewall and NAT validation), and validate_system.go (364 lines, system configuration, users, groups, and sysctl validation). This refactoring improved maintainability by organizing validation logic into focused modules.

PR #419 split internal/converter/builder/builder.go into domain-specific files to comply with the project's 800-line guideline: builder_services.go for DHCP/DNS/SNMP/NTP/load balancer services and builder_vpn.go for IPsec/OpenVPN/VLAN/routing/HA configuration. This refactoring follows the file-split pattern established in PR #415 and PR #417, adding 2 production files to the internal/converter/ package while fixing inconsistent markdown table escaping in VPN-related fields.

Relevant Code Files#

CategoryFile PathDescription
Analysisinternal/analysis/detect.goDetection logic for dead rules, unused interfaces, security/performance/consistency issues
Analysisinternal/analysis/statistics.goStatistics computation and complexity scoring
Analysisinternal/analysis/rules.goRule equivalence checking
Analysisinternal/analysis/helpers.goHelper functions for interface and DHCP scope lookups
Analysisinternal/analysis/finding.goCanonical Finding struct and Severity type
Architectureinternal/compliance/interfaces.goPlugin interface definitions
Architectureinternal/audit/plugin.goThread-safe plugin registry
Architecturecmd/context.goCommandContext dependency injection pattern
Securityinternal/cfgparser/xml.goSecurity-first XML parser with context cancellation
Data Modelpkg/schema/opnsense/opnsense.goRoot XML DTO structure (96 structs total)
Data Modelpkg/model/device.goPlatform-agnostic CommonDevice model (94 structs total)
Data Modelpkg/model/enrichment.goComplianceResults and compliance data structures (7 new structs in PR #400)
Data Modelpkg/model/services.goService definitions (26 structs, 536 lines)
Parserpkg/parser/factory.goFactory and DeviceParser interface (renamed from ParserFactory in PR #404)
Parserpkg/parser/opnsense/parser.goOPNsense parser implementation
Parserpkg/parser/opnsense/converter.goSchema-to-CommonDevice converter with conversion warnings
CLIcmd/audit_handler.goAudit command handler (maps audit.Report to ComplianceResults)
CLIcmd/convert.goMain conversion command (803 lines)
CLIcmd/root.goRoot CLI command definition (376 lines)
Conversioninternal/converter/builder/builder.goReport builder with BuildAuditSection() (added in PR #400)
Conversioninternal/converter/enrichment.goExport preparation delegating to internal/analysis/ (refactored in PR #409)
Conversioninternal/converter/hybrid_generator.goModern programmatic markdown generator (production)
Conversioninternal/converter/markdown.goLegacy markdown converter (tests only)
Processinginternal/processor/analyze.goAnalysis engine delegating to internal/analysis/ (refactored in PR #409)
Processinginternal/processor/report.goReport types, constructors, accessors, JSON/YAML serialization (256 lines, split from 820-line file in PR #415)
Processinginternal/processor/report_statistics.goStatistics computation and translation (218 lines, extracted in PR #415)
Processinginternal/processor/report_markdown.goMarkdown rendering and formatting (368 lines, extracted in PR #415)
Processinginternal/processor/concurrent.goWorker pool implementation
Validationinternal/validator/opnsense.goMain validator entry point and helper functions (28 lines, refactored in PR #417)
Validationinternal/validator/validate_network.goNetwork and DHCP validation (259 lines, extracted in PR #417)
Validationinternal/validator/validate_security.goFirewall and NAT validation (255 lines, extracted in PR #417)
Validationinternal/validator/validate_system.goSystem configuration validation (364 lines, extracted in PR #417)
CI/CD.github/workflows/ci.ymlMain CI pipeline with 6 jobs
CI/CD.github/workflows/release.ymlRelease workflow with SLSA provenance
CI/CD.github/workflows/benchmarks.ymlPerformance regression detection
Configuration.golangci.ymlLinter configuration (70+ linters)
Configuration.goreleaser.yamlMulti-platform release configuration
Configurationgo.modGo 1.26, 19 direct + 70 indirect dependencies
Configurationmise.tomlDevelopment toolchain management (17 tools)
ConfigurationjustfileTask automation and local/CI parity
Testinginternal/converter/golden_test.goMarkdown golden file tests
Testinginternal/diff/formatters/golden_test.goDiff formatter golden file tests
DocumentationAGENTS.mdTesting standards and requirements
  • Architecture Review Findings - Detailed analysis of architectural patterns, strengths, and improvement areas
  • Plugin System Design - Compliance checking plugin architecture with thread-safe registry
  • Two-Layer Data Model - XML DTO layer (pkg/schema/opnsense/) and platform-agnostic domain layer (pkg/model/)
  • Supply Chain Security - SLSA provenance, Cosign signing, SBOM generation
  • Testing Practices - Golden file testing, race detection, 85% coverage enforcement
  • CI/CD Pipeline - Multi-stage workflows for testing, security, documentation, and releases
Codebase Metrics And Package Breakdown | Dosu