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:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user