grafana-backuper/pkg/grafanabackuper/backup.go

160 lines
4.5 KiB
Go
Raw Permalink Normal View History

package grafanabackuper
import (
"context"
"encoding/json"
"errors"
"slices"
"git.ar21.de/yolokube/grafana-backuper/internal/config"
"git.ar21.de/yolokube/grafana-backuper/pkg/git"
"git.ar21.de/yolokube/grafana-backuper/pkg/grafana"
)
var ErrAlreadyCommited = errors.New("already committed")
type BackupClient struct {
client *Client
}
func (b *BackupClient) Start(ctx context.Context, cfg *config.Config) error {
b.client.logger.Debug().Str("search-type", string(grafana.SearchTypeDashboard)).Msg("Searching dashboards by type")
dashboards, _, err := b.client.grafana.File.Search(ctx, grafana.WithType(grafana.SearchTypeDashboard))
if err != nil {
return err
}
b.client.logger.Debug().
Str("search-type", string(grafana.SearchTypeDashboard)).
Int("counter", len(dashboards)).
Msg("Found dashboards")
for _, dashboardInfo := range dashboards {
b.client.logger.Debug().
Str("dashboard-uid", dashboardInfo.UID).
Str("dashboard", dashboardInfo.Title).
Msg("Fetching dashboard data")
var dashboard *grafana.Dashboard
dashboard, _, err = b.client.grafana.Dashboard.Get(ctx, dashboardInfo.UID)
if err != nil {
return err
}
b.client.logger.Debug().
Str("dashboard-uid", dashboardInfo.UID).
Str("dashboard", dashboardInfo.Title).
Msg("Fetching dashboard versions")
var versions []*grafana.DashboardVersion
versions, _, err = b.client.grafana.DashboardVersion.List(ctx, dashboardInfo.UID)
if err != nil {
return err
}
b.client.logger.Debug().
Str("dashboard-uid", dashboardInfo.UID).
Str("dashboard", dashboardInfo.Title).
Int("counter", len(versions)).
Msg("Found dashboard versions")
slices.Reverse(versions)
uncommitedVersion := cfg.ForceCommits
for _, version := range versions {
b.client.logger.Debug().
Str("dashboard-uid", dashboardInfo.UID).
Uint("version", version.Version).
Msg("Fetching version data")
var dashboardVersion *grafana.DashboardVersion
dashboardVersion, _, err = b.client.grafana.DashboardVersion.Get(ctx, dashboardInfo.UID, version.Version)
if err != nil {
return err
}
var commitmsg string
commitmsg, err = b.commitDashboardVersion(
dashboard,
dashboardVersion,
dashboardInfo,
cfg,
uncommitedVersion,
)
if errors.Is(err, ErrAlreadyCommited) {
b.client.logger.Info().Str("commit-msg", commitmsg).Msg("Already committed")
continue
} else if err != nil {
return err
}
uncommitedVersion = true
b.client.logger.Info().Str("commit-msg", commitmsg).Msg("Commit created")
}
}
if !b.client.git.HasChanges() {
return nil
}
return b.client.git.Push(ctx)
}
func (b *BackupClient) commitDashboardVersion(
dashboard *grafana.Dashboard,
dashboardVersion *grafana.DashboardVersion,
dashboardInfo *grafana.SearchResult,
cfg *config.Config,
force bool,
) (string, error) {
commitmsg := Message{
ID: dashboardVersion.ID,
Path: dashboardInfo.Title,
Title: dashboardVersion.Message,
UID: dashboardInfo.UID,
}.String()
b.client.logger.Debug().Str("commit", commitmsg).Msg("Checking commit existence")
if !force && b.client.git.CommitExists(commitmsg) {
return commitmsg, ErrAlreadyCommited
}
b.updateDashboardInfo(dashboard, dashboardVersion)
b.client.logger.Debug().
Str("folder", dashboard.FolderTitle).
Str("dashboard-uid", dashboardVersion.DashboardUID).
Msg("Marshalling the dashboard version data")
data, err := json.MarshalIndent(grafana.SchemaFromDashboardMeta(dashboard), "", " ")
if err != nil {
return commitmsg, err
}
commitOpts := []git.CommitOption{
git.WithAuthor(dashboardVersion.CreatedBy, ""),
git.WithFileContent(data, dashboardInfo.Title, dashboard.FolderTitle),
}
if b.client.signer != nil {
commitOpts = append(commitOpts, git.WithSigner(*b.client.signer))
}
if cfg.GitUser != "" {
commitOpts = append(commitOpts, git.WithCommitter(cfg.GitUser, cfg.GitEmail))
}
commit := b.client.git.NewCommit(commitOpts...)
b.client.logger.Debug().Str("commit", commitmsg).Msg("Creating new commit")
return commitmsg, commit.Create(commitmsg)
}
func (b *BackupClient) updateDashboardInfo(d *grafana.Dashboard, dv *grafana.DashboardVersion) {
b.client.logger.Debug().
Str("dashboard-uid", dv.DashboardUID).
Str("folder", d.FolderTitle).
Msg("Updating dashboard information")
d.Dashboard = dv.Data
d.UpdatedBy = dv.CreatedBy
d.Updated = dv.Created
d.Version = dv.Version
b.client.logger.Debug().
Str("dashboard-uid", dv.DashboardUID).
Str("folder", d.FolderTitle).
Msg("Updated dashboard information successfully")
}