package cmd import ( "context" "errors" "fmt" "slices" "git.ar21.de/yolokube/grafana-backuper/internal/config" "git.ar21.de/yolokube/grafana-backuper/internal/helper" "git.ar21.de/yolokube/grafana-backuper/pkg/git" "git.ar21.de/yolokube/grafana-backuper/pkg/grafana" "github.com/spf13/cobra" ) func NewBackupCommand(c *config.Config) *cobra.Command { backupCmd := &cobra.Command{ Use: "backup", Short: "Back up the dashboards from grafana to a git repository.", Long: "Back up the dashboards from grafana to a git repository.", RunE: func(cmd *cobra.Command, _ []string) error { return backup(cmd.Context(), c) }, PreRunE: func(_ *cobra.Command, _ []string) error { return c.Validate() }, } backupCmd.PersistentFlags().BoolVar(&c.ForceCommits, "force", false, "Force git commits / ignore existence check") backupCmd.PersistentFlags().StringVar(&c.GitEmail, "git-email", "", "Git email address") backupCmd.PersistentFlags().StringVar(&c.GPGKey, "signing-key", "", "Path to the GPG signing key") return backupCmd } func backup(ctx context.Context, c *config.Config) error { client := grafana.NewClient( c.GrafanaURL, grafana.WithToken(c.GrafanaToken), ) project, err := helper.PrepareProject(ctx, c) if err != nil { return err } var signer git.SignKey if c.GPGKey != "" { signer = git.SignKey{KeyFile: c.GPGKey} if err = signer.ReadKeyFile(); err != nil { return err } } dashboards, _, err := client.File.Search(ctx, grafana.WithType(grafana.SearchTypeDashboard)) if err != nil { return err } for _, dashboardInfo := range dashboards { var dashboard *grafana.Dashboard dashboard, _, err = client.Dashboard.Get(ctx, dashboardInfo.UID) if err != nil { return err } var versions []*grafana.DashboardVersion versions, _, err = client.DashboardVersion.List(ctx, dashboardInfo.UID) if err != nil { return err } slices.Reverse(versions) uncommitedVersion := c.ForceCommits for _, version := range versions { var dashboardVersion *grafana.DashboardVersion dashboardVersion, _, err = client.DashboardVersion.Get(ctx, dashboardInfo.UID, version.Version) if err != nil { return err } var commitMsg string commitMsg, err = helper.CommitVersion( dashboard, dashboardVersion, dashboardInfo, project, c, signer, uncommitedVersion, ) if errors.Is(err, helper.ErrAlreadyCommited) { fmt.Fprintf(c.Output, "%s -> %v\n", commitMsg, err) continue } else if err != nil { return err } uncommitedVersion = true fmt.Fprintln(c.Output, commitMsg) } } if !project.HasChanges() { return nil } return project.Push(ctx) }