feat(engine): physical backup revolution - XtraBackup capabilities in pure Go

Why wrap external tools when you can BE the tool?

New physical backup engines:
• MySQL Clone Plugin - native 8.0.17+ physical backup
• Filesystem Snapshots - LVM/ZFS/Btrfs orchestration
• Binlog Streaming - continuous backup with seconds RPO
• Parallel Cloud Upload - stream directly to S3, skip local disk

Smart engine selection automatically picks the optimal strategy based on:
- MySQL version and edition
- Available filesystem features
- Database size
- Cloud connectivity

Zero external dependencies. Single binary. Enterprise capabilities.

Commercial backup vendors: we need to talk.
This commit is contained in:
2025-12-13 21:21:17 +01:00
parent f69bfe7071
commit dbb0f6f942
27 changed files with 7559 additions and 268 deletions

View File

@@ -157,12 +157,12 @@ func (g *Generator) collectEvidence() ([]Evidence, error) {
Source: "catalog",
CollectedAt: time.Now(),
Data: map[string]interface{}{
"total_backups": stats.TotalBackups,
"oldest_backup": stats.OldestBackup,
"newest_backup": stats.NewestBackup,
"average_size": stats.AvgSize,
"total_size": stats.TotalSize,
"databases": len(stats.ByDatabase),
"total_backups": stats.TotalBackups,
"oldest_backup": stats.OldestBackup,
"newest_backup": stats.NewestBackup,
"average_size": stats.AvgSize,
"total_size": stats.TotalSize,
"databases": len(stats.ByDatabase),
},
})
}
@@ -376,34 +376,34 @@ func (g *Generator) createFinding(ctrl *Control, report *Report) *Finding {
}
return &Finding{
ID: fmt.Sprintf("FND-%s-%d", ctrl.ID, time.Now().UnixNano()),
ControlID: ctrl.ID,
Type: findingType,
Severity: severity,
Title: fmt.Sprintf("%s: %s", ctrl.Reference, ctrl.Name),
Description: ctrl.Notes,
Impact: fmt.Sprintf("Non-compliance with %s requirements", report.Type),
ID: fmt.Sprintf("FND-%s-%d", ctrl.ID, time.Now().UnixNano()),
ControlID: ctrl.ID,
Type: findingType,
Severity: severity,
Title: fmt.Sprintf("%s: %s", ctrl.Reference, ctrl.Name),
Description: ctrl.Notes,
Impact: fmt.Sprintf("Non-compliance with %s requirements", report.Type),
Recommendation: g.getRecommendation(ctrl.ID),
Status: FindingOpen,
DetectedAt: time.Now(),
Evidence: ctrl.Evidence,
Status: FindingOpen,
DetectedAt: time.Now(),
Evidence: ctrl.Evidence,
}
}
// getRecommendation returns remediation recommendation for a control
func (g *Generator) getRecommendation(controlID string) string {
recommendations := map[string]string{
"CC6.1": "Enable encryption for all backups using AES-256",
"CC6.7": "Ensure all backup transfers use TLS",
"A1.1": "Establish and document backup schedule",
"A1.2": "Schedule and perform regular DR drill tests",
"A1.3": "Document and test recovery procedures",
"A1.4": "Develop and test disaster recovery plan",
"PI1.1": "Enable checksum verification for all backups",
"C1.2": "Implement and document retention policies",
"CC6.1": "Enable encryption for all backups using AES-256",
"CC6.7": "Ensure all backup transfers use TLS",
"A1.1": "Establish and document backup schedule",
"A1.2": "Schedule and perform regular DR drill tests",
"A1.3": "Document and test recovery procedures",
"A1.4": "Develop and test disaster recovery plan",
"PI1.1": "Enable checksum verification for all backups",
"C1.2": "Implement and document retention policies",
"164.312a2iv": "Enable HIPAA-compliant encryption (AES-256)",
"164.308a7iD": "Test backup recoverability quarterly",
"PCI-3.4": "Encrypt all backups containing cardholder data",
"PCI-3.4": "Encrypt all backups containing cardholder data",
}
if rec, ok := recommendations[controlID]; ok {

View File

@@ -155,12 +155,12 @@ type HTMLFormatter struct{}
// Format writes the report as HTML
func (f *HTMLFormatter) Format(report *Report, w io.Writer) error {
tmpl := template.Must(template.New("report").Funcs(template.FuncMap{
"statusIcon": StatusIcon,
"statusClass": statusClass,
"severityIcon": SeverityIcon,
"statusIcon": StatusIcon,
"statusClass": statusClass,
"severityIcon": SeverityIcon,
"severityClass": severityClass,
"formatTime": func(t time.Time) string { return t.Format("2006-01-02 15:04:05") },
"formatDate": func(t time.Time) string { return t.Format("2006-01-02") },
"formatTime": func(t time.Time) string { return t.Format("2006-01-02 15:04:05") },
"formatDate": func(t time.Time) string { return t.Format("2006-01-02") },
}).Parse(htmlTemplate))
return tmpl.Execute(w, report)
@@ -500,7 +500,7 @@ func (f *ConsoleFormatter) Format(report *Report, w io.Writer) error {
fmt.Fprintf(w, "%s\n\n", strings.Repeat("=", 60))
fmt.Fprintf(w, " Generated: %s\n", report.GeneratedAt.Format("2006-01-02 15:04:05"))
fmt.Fprintf(w, " Period: %s to %s\n",
fmt.Fprintf(w, " Period: %s to %s\n",
report.PeriodStart.Format("2006-01-02"),
report.PeriodEnd.Format("2006-01-02"))
fmt.Fprintf(w, " Status: %s %s\n", StatusIcon(report.Status), report.Status)

View File

@@ -23,30 +23,30 @@ const (
type ComplianceStatus string
const (
StatusCompliant ComplianceStatus = "compliant"
StatusNonCompliant ComplianceStatus = "non_compliant"
StatusPartial ComplianceStatus = "partial"
StatusCompliant ComplianceStatus = "compliant"
StatusNonCompliant ComplianceStatus = "non_compliant"
StatusPartial ComplianceStatus = "partial"
StatusNotApplicable ComplianceStatus = "not_applicable"
StatusUnknown ComplianceStatus = "unknown"
StatusUnknown ComplianceStatus = "unknown"
)
// Report represents a compliance report
type Report struct {
ID string `json:"id"`
Type ReportType `json:"type"`
Title string `json:"title"`
Description string `json:"description"`
GeneratedAt time.Time `json:"generated_at"`
GeneratedBy string `json:"generated_by"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
Status ComplianceStatus `json:"overall_status"`
Score float64 `json:"score"` // 0-100
Categories []Category `json:"categories"`
Summary Summary `json:"summary"`
Findings []Finding `json:"findings"`
Evidence []Evidence `json:"evidence"`
Metadata map[string]string `json:"metadata,omitempty"`
ID string `json:"id"`
Type ReportType `json:"type"`
Title string `json:"title"`
Description string `json:"description"`
GeneratedAt time.Time `json:"generated_at"`
GeneratedBy string `json:"generated_by"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
Status ComplianceStatus `json:"overall_status"`
Score float64 `json:"score"` // 0-100
Categories []Category `json:"categories"`
Summary Summary `json:"summary"`
Findings []Finding `json:"findings"`
Evidence []Evidence `json:"evidence"`
Metadata map[string]string `json:"metadata,omitempty"`
}
// Category represents a compliance category
@@ -62,40 +62,40 @@ type Category struct {
// Control represents a compliance control
type Control struct {
ID string `json:"id"`
Reference string `json:"reference"` // e.g., "SOC2 CC6.1"
Name string `json:"name"`
Description string `json:"description"`
Status ComplianceStatus `json:"status"`
Evidence []string `json:"evidence_ids,omitempty"`
Findings []string `json:"finding_ids,omitempty"`
LastChecked time.Time `json:"last_checked"`
Notes string `json:"notes,omitempty"`
ID string `json:"id"`
Reference string `json:"reference"` // e.g., "SOC2 CC6.1"
Name string `json:"name"`
Description string `json:"description"`
Status ComplianceStatus `json:"status"`
Evidence []string `json:"evidence_ids,omitempty"`
Findings []string `json:"finding_ids,omitempty"`
LastChecked time.Time `json:"last_checked"`
Notes string `json:"notes,omitempty"`
}
// Finding represents a compliance finding
type Finding struct {
ID string `json:"id"`
ControlID string `json:"control_id"`
Type FindingType `json:"type"`
Severity FindingSeverity `json:"severity"`
Title string `json:"title"`
Description string `json:"description"`
Impact string `json:"impact"`
Recommendation string `json:"recommendation"`
Status FindingStatus `json:"status"`
DetectedAt time.Time `json:"detected_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
Evidence []string `json:"evidence_ids,omitempty"`
ID string `json:"id"`
ControlID string `json:"control_id"`
Type FindingType `json:"type"`
Severity FindingSeverity `json:"severity"`
Title string `json:"title"`
Description string `json:"description"`
Impact string `json:"impact"`
Recommendation string `json:"recommendation"`
Status FindingStatus `json:"status"`
DetectedAt time.Time `json:"detected_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
Evidence []string `json:"evidence_ids,omitempty"`
}
// FindingType represents the type of finding
type FindingType string
const (
FindingGap FindingType = "gap"
FindingViolation FindingType = "violation"
FindingObservation FindingType = "observation"
FindingGap FindingType = "gap"
FindingViolation FindingType = "violation"
FindingObservation FindingType = "observation"
FindingRecommendation FindingType = "recommendation"
)
@@ -133,57 +133,57 @@ type Evidence struct {
type EvidenceType string
const (
EvidenceBackupLog EvidenceType = "backup_log"
EvidenceRestoreLog EvidenceType = "restore_log"
EvidenceDrillResult EvidenceType = "drill_result"
EvidenceBackupLog EvidenceType = "backup_log"
EvidenceRestoreLog EvidenceType = "restore_log"
EvidenceDrillResult EvidenceType = "drill_result"
EvidenceEncryptionProof EvidenceType = "encryption_proof"
EvidenceRetentionProof EvidenceType = "retention_proof"
EvidenceAccessLog EvidenceType = "access_log"
EvidenceAuditLog EvidenceType = "audit_log"
EvidenceConfiguration EvidenceType = "configuration"
EvidenceScreenshot EvidenceType = "screenshot"
EvidenceOther EvidenceType = "other"
EvidenceRetentionProof EvidenceType = "retention_proof"
EvidenceAccessLog EvidenceType = "access_log"
EvidenceAuditLog EvidenceType = "audit_log"
EvidenceConfiguration EvidenceType = "configuration"
EvidenceScreenshot EvidenceType = "screenshot"
EvidenceOther EvidenceType = "other"
)
// Summary provides a high-level overview
type Summary struct {
TotalControls int `json:"total_controls"`
CompliantControls int `json:"compliant_controls"`
NonCompliantControls int `json:"non_compliant_controls"`
PartialControls int `json:"partial_controls"`
NotApplicable int `json:"not_applicable"`
OpenFindings int `json:"open_findings"`
CriticalFindings int `json:"critical_findings"`
HighFindings int `json:"high_findings"`
MediumFindings int `json:"medium_findings"`
LowFindings int `json:"low_findings"`
ComplianceRate float64 `json:"compliance_rate"`
RiskScore float64 `json:"risk_score"`
TotalControls int `json:"total_controls"`
CompliantControls int `json:"compliant_controls"`
NonCompliantControls int `json:"non_compliant_controls"`
PartialControls int `json:"partial_controls"`
NotApplicable int `json:"not_applicable"`
OpenFindings int `json:"open_findings"`
CriticalFindings int `json:"critical_findings"`
HighFindings int `json:"high_findings"`
MediumFindings int `json:"medium_findings"`
LowFindings int `json:"low_findings"`
ComplianceRate float64 `json:"compliance_rate"`
RiskScore float64 `json:"risk_score"`
}
// ReportConfig configures report generation
type ReportConfig struct {
Type ReportType `json:"type"`
Title string `json:"title"`
Description string `json:"description"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
IncludeDatabases []string `json:"include_databases,omitempty"`
ExcludeDatabases []string `json:"exclude_databases,omitempty"`
CatalogPath string `json:"catalog_path"`
OutputFormat OutputFormat `json:"output_format"`
OutputPath string `json:"output_path"`
IncludeEvidence bool `json:"include_evidence"`
CustomControls []Control `json:"custom_controls,omitempty"`
Type ReportType `json:"type"`
Title string `json:"title"`
Description string `json:"description"`
PeriodStart time.Time `json:"period_start"`
PeriodEnd time.Time `json:"period_end"`
IncludeDatabases []string `json:"include_databases,omitempty"`
ExcludeDatabases []string `json:"exclude_databases,omitempty"`
CatalogPath string `json:"catalog_path"`
OutputFormat OutputFormat `json:"output_format"`
OutputPath string `json:"output_path"`
IncludeEvidence bool `json:"include_evidence"`
CustomControls []Control `json:"custom_controls,omitempty"`
}
// OutputFormat represents report output format
type OutputFormat string
const (
FormatJSON OutputFormat = "json"
FormatHTML OutputFormat = "html"
FormatPDF OutputFormat = "pdf"
FormatJSON OutputFormat = "json"
FormatHTML OutputFormat = "html"
FormatPDF OutputFormat = "pdf"
FormatMarkdown OutputFormat = "markdown"
)