generate excel worksheets when data is available instead of on-demand
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -637,6 +639,29 @@ func CreateTableReport(logger *slog.Logger, Database db.Database, ctx context.Co
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// SaveTableReport renders a table report and writes it to the destination directory with a .xlsx extension.
|
||||
func SaveTableReport(logger *slog.Logger, Database db.Database, ctx context.Context, tableName, destDir string) (string, error) {
|
||||
if err := db.ValidateTableName(tableName); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if strings.TrimSpace(destDir) == "" {
|
||||
return "", fmt.Errorf("destination directory is empty")
|
||||
}
|
||||
if err := os.MkdirAll(destDir, 0o755); err != nil {
|
||||
return "", fmt.Errorf("failed to create reports directory: %w", err)
|
||||
}
|
||||
|
||||
data, err := CreateTableReport(logger, Database, ctx, tableName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
filename := filepath.Join(destDir, fmt.Sprintf("%s.xlsx", tableName))
|
||||
if err := os.WriteFile(filename, data, 0o644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filename, nil
|
||||
}
|
||||
|
||||
func addTotalsChartSheet(logger *slog.Logger, database db.Database, ctx context.Context, xlsx *excelize.File, tableName string) {
|
||||
if strings.HasPrefix(tableName, "inventory_daily_summary_") {
|
||||
suffix := strings.TrimPrefix(tableName, "inventory_daily_summary_")
|
||||
|
||||
@@ -40,6 +40,7 @@ type SettingsYML struct {
|
||||
HourlySnapshotMaxAgeDays int `yaml:"hourly_snapshot_max_age_days"`
|
||||
DailySnapshotMaxAgeMonths int `yaml:"daily_snapshot_max_age_months"`
|
||||
SnapshotCleanupCron string `yaml:"snapshot_cleanup_cron"`
|
||||
ReportsDir string `yaml:"reports_dir"`
|
||||
HourlyJobTimeoutSeconds int `yaml:"hourly_job_timeout_seconds"`
|
||||
HourlySnapshotTimeoutSeconds int `yaml:"hourly_snapshot_timeout_seconds"`
|
||||
DailyJobTimeoutSeconds int `yaml:"daily_job_timeout_seconds"`
|
||||
|
||||
@@ -168,6 +168,10 @@ func (c *CronTask) RunVcenterSnapshotHourly(ctx context.Context, logger *slog.Lo
|
||||
c.Logger.Warn("failed to register hourly snapshot", "error", err, "table", tableName)
|
||||
}
|
||||
|
||||
if err := c.generateReport(ctx, tableName); err != nil {
|
||||
c.Logger.Warn("failed to generate hourly report", "error", err, "table", tableName)
|
||||
}
|
||||
|
||||
c.Logger.Debug("Finished hourly vcenter snapshot", "vcenter_count", len(c.Settings.Values.Settings.VcenterAddresses), "table", tableName, "row_count", rowCount)
|
||||
return nil
|
||||
}
|
||||
@@ -312,6 +316,10 @@ func (c *CronTask) aggregateDailySummary(ctx context.Context, targetTime time.Ti
|
||||
c.Logger.Warn("failed to register daily snapshot", "error", err, "table", summaryTable)
|
||||
}
|
||||
|
||||
if err := c.generateReport(ctx, summaryTable); err != nil {
|
||||
c.Logger.Warn("failed to generate daily report", "error", err, "table", summaryTable)
|
||||
}
|
||||
|
||||
c.Logger.Debug("Finished daily inventory aggregation", "summary_table", summaryTable)
|
||||
return nil
|
||||
}
|
||||
@@ -431,6 +439,10 @@ func (c *CronTask) aggregateMonthlySummary(ctx context.Context, targetMonth time
|
||||
c.Logger.Warn("failed to register monthly snapshot", "error", err, "table", monthlyTable)
|
||||
}
|
||||
|
||||
if err := c.generateReport(ctx, monthlyTable); err != nil {
|
||||
c.Logger.Warn("failed to generate monthly report", "error", err, "table", monthlyTable)
|
||||
}
|
||||
|
||||
c.Logger.Debug("Finished monthly inventory aggregation", "summary_table", monthlyTable)
|
||||
return nil
|
||||
}
|
||||
@@ -718,6 +730,21 @@ func normalizeResourcePool(value string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CronTask) reportsDir() string {
|
||||
if c.Settings != nil && c.Settings.Values != nil {
|
||||
if dir := strings.TrimSpace(c.Settings.Values.Settings.ReportsDir); dir != "" {
|
||||
return dir
|
||||
}
|
||||
}
|
||||
return "/var/lib/vctp/reports"
|
||||
}
|
||||
|
||||
func (c *CronTask) generateReport(ctx context.Context, tableName string) error {
|
||||
dest := c.reportsDir()
|
||||
_, err := report.SaveTableReport(c.Logger, c.Database, ctx, tableName, dest)
|
||||
return err
|
||||
}
|
||||
|
||||
func snapshotFromVM(vmObject *mo.VirtualMachine, vc *vcenter.Vcenter, snapshotTime time.Time, inv *queries.Inventory, hostLookup map[string]vcenter.HostLookup, folderLookup vcenter.FolderLookup, rpLookup map[string]string) (inventorySnapshotRow, error) {
|
||||
if vmObject == nil {
|
||||
return inventorySnapshotRow{}, fmt.Errorf("missing VM object")
|
||||
|
||||
Reference in New Issue
Block a user