Add storage location to backup get/describe

Fixes #775

Also conforms ark imports to https://github.com/heptio/ark/issues/494

Signed-off-by: Nolan Brubaker <nolan@heptio.com>
pull/799/head
Nolan Brubaker 2018-08-20 17:17:13 -04:00 committed by Steve Kriss
parent cf7c8587f0
commit 833a6307a9
2 changed files with 32 additions and 27 deletions

View File

@ -21,19 +21,19 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/heptio/ark/pkg/apis/ark/v1" arkv1api "github.com/heptio/ark/pkg/apis/ark/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
// DescribeBackup describes a backup in human-readable format. // DescribeBackup describes a backup in human-readable format.
func DescribeBackup(backup *v1.Backup, deleteRequests []v1.DeleteBackupRequest, podVolumeBackups []v1.PodVolumeBackup, volumeDetails bool) string { func DescribeBackup(backup *arkv1api.Backup, deleteRequests []arkv1api.DeleteBackupRequest, podVolumeBackups []arkv1api.PodVolumeBackup, volumeDetails bool) string {
return Describe(func(d *Describer) { return Describe(func(d *Describer) {
d.DescribeMetadata(backup.ObjectMeta) d.DescribeMetadata(backup.ObjectMeta)
d.Println() d.Println()
phase := backup.Status.Phase phase := backup.Status.Phase
if phase == "" { if phase == "" {
phase = v1.BackupPhaseNew phase = arkv1api.BackupPhaseNew
} }
d.Printf("Phase:\t%s\n", phase) d.Printf("Phase:\t%s\n", phase)
@ -56,7 +56,7 @@ func DescribeBackup(backup *v1.Backup, deleteRequests []v1.DeleteBackupRequest,
} }
// DescribeBackupSpec describes a backup spec in human-readable format. // DescribeBackupSpec describes a backup spec in human-readable format.
func DescribeBackupSpec(d *Describer, spec v1.BackupSpec) { func DescribeBackupSpec(d *Describer, spec arkv1api.BackupSpec) {
// TODO make a helper for this and use it in all the describers. // TODO make a helper for this and use it in all the describers.
d.Printf("Namespaces:\n") d.Printf("Namespaces:\n")
var s string var s string
@ -97,6 +97,9 @@ func DescribeBackupSpec(d *Describer, spec v1.BackupSpec) {
} }
d.Printf("Label selector:\t%s\n", s) d.Printf("Label selector:\t%s\n", s)
d.Println()
d.Printf("Storage Location:\t%s\n", spec.StorageLocation)
d.Println() d.Println()
d.Printf("Snapshot PVs:\t%s\n", BoolPointerString(spec.SnapshotVolumes, "false", "true", "auto")) d.Printf("Snapshot PVs:\t%s\n", BoolPointerString(spec.SnapshotVolumes, "false", "true", "auto"))
@ -164,7 +167,7 @@ func DescribeBackupSpec(d *Describer, spec v1.BackupSpec) {
} }
// DescribeBackupStatus describes a backup status in human-readable format. // DescribeBackupStatus describes a backup status in human-readable format.
func DescribeBackupStatus(d *Describer, status v1.BackupStatus) { func DescribeBackupStatus(d *Describer, status arkv1api.BackupStatus) {
d.Printf("Backup Format Version:\t%d\n", status.Version) d.Printf("Backup Format Version:\t%d\n", status.Version)
d.Println() d.Println()
@ -213,7 +216,7 @@ func DescribeBackupStatus(d *Describer, status v1.BackupStatus) {
} }
// DescribeDeleteBackupRequests describes delete backup requests in human-readable format. // DescribeDeleteBackupRequests describes delete backup requests in human-readable format.
func DescribeDeleteBackupRequests(d *Describer, requests []v1.DeleteBackupRequest) { func DescribeDeleteBackupRequests(d *Describer, requests []arkv1api.DeleteBackupRequest) {
d.Printf("Deletion Attempts") d.Printf("Deletion Attempts")
if count := failedDeletionCount(requests); count > 0 { if count := failedDeletionCount(requests); count > 0 {
d.Printf(" (%d failed)", count) d.Printf(" (%d failed)", count)
@ -238,10 +241,10 @@ func DescribeDeleteBackupRequests(d *Describer, requests []v1.DeleteBackupReques
} }
} }
func failedDeletionCount(requests []v1.DeleteBackupRequest) int { func failedDeletionCount(requests []arkv1api.DeleteBackupRequest) int {
var count int var count int
for _, req := range requests { for _, req := range requests {
if req.Status.Phase == v1.DeleteBackupRequestPhaseProcessed && len(req.Status.Errors) > 0 { if req.Status.Phase == arkv1api.DeleteBackupRequestPhaseProcessed && len(req.Status.Errors) > 0 {
count++ count++
} }
} }
@ -249,7 +252,7 @@ func failedDeletionCount(requests []v1.DeleteBackupRequest) int {
} }
// DescribePodVolumeBackups describes pod volume backups in human-readable format. // DescribePodVolumeBackups describes pod volume backups in human-readable format.
func DescribePodVolumeBackups(d *Describer, backups []v1.PodVolumeBackup, details bool) { func DescribePodVolumeBackups(d *Describer, backups []arkv1api.PodVolumeBackup, details bool) {
if details { if details {
d.Printf("Restic Backups:\n") d.Printf("Restic Backups:\n")
} else { } else {
@ -261,10 +264,10 @@ func DescribePodVolumeBackups(d *Describer, backups []v1.PodVolumeBackup, detail
// go through phases in a specific order // go through phases in a specific order
for _, phase := range []string{ for _, phase := range []string{
string(v1.PodVolumeBackupPhaseCompleted), string(arkv1api.PodVolumeBackupPhaseCompleted),
string(v1.PodVolumeBackupPhaseFailed), string(arkv1api.PodVolumeBackupPhaseFailed),
"In Progress", "In Progress",
string(v1.PodVolumeBackupPhaseNew), string(arkv1api.PodVolumeBackupPhaseNew),
} { } {
if len(backupsByPhase[phase]) == 0 { if len(backupsByPhase[phase]) == 0 {
continue continue
@ -293,15 +296,15 @@ func DescribePodVolumeBackups(d *Describer, backups []v1.PodVolumeBackup, detail
} }
} }
func groupByPhase(backups []v1.PodVolumeBackup) map[string][]v1.PodVolumeBackup { func groupByPhase(backups []arkv1api.PodVolumeBackup) map[string][]arkv1api.PodVolumeBackup {
backupsByPhase := make(map[string][]v1.PodVolumeBackup) backupsByPhase := make(map[string][]arkv1api.PodVolumeBackup)
phaseToGroup := map[v1.PodVolumeBackupPhase]string{ phaseToGroup := map[arkv1api.PodVolumeBackupPhase]string{
v1.PodVolumeBackupPhaseCompleted: string(v1.PodVolumeBackupPhaseCompleted), arkv1api.PodVolumeBackupPhaseCompleted: string(arkv1api.PodVolumeBackupPhaseCompleted),
v1.PodVolumeBackupPhaseFailed: string(v1.PodVolumeBackupPhaseFailed), arkv1api.PodVolumeBackupPhaseFailed: string(arkv1api.PodVolumeBackupPhaseFailed),
v1.PodVolumeBackupPhaseInProgress: "In Progress", arkv1api.PodVolumeBackupPhaseInProgress: "In Progress",
v1.PodVolumeBackupPhaseNew: string(v1.PodVolumeBackupPhaseNew), arkv1api.PodVolumeBackupPhaseNew: string(arkv1api.PodVolumeBackupPhaseNew),
"": string(v1.PodVolumeBackupPhaseNew), "": string(arkv1api.PodVolumeBackupPhaseNew),
} }
for _, backup := range backups { for _, backup := range backups {

View File

@ -27,14 +27,14 @@ import (
"k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/util/duration"
"k8s.io/kubernetes/pkg/printers" "k8s.io/kubernetes/pkg/printers"
"github.com/heptio/ark/pkg/apis/ark/v1" arkv1api "github.com/heptio/ark/pkg/apis/ark/v1"
) )
var ( var (
backupColumns = []string{"NAME", "STATUS", "CREATED", "EXPIRES", "SELECTOR"} backupColumns = []string{"NAME", "STATUS", "CREATED", "EXPIRES", "STORAGE LOCATION", "SELECTOR"}
) )
func printBackupList(list *v1.BackupList, w io.Writer, options printers.PrintOptions) error { func printBackupList(list *arkv1api.BackupList, w io.Writer, options printers.PrintOptions) error {
sortBackupsByPrefixAndTimestamp(list) sortBackupsByPrefixAndTimestamp(list)
for i := range list.Items { for i := range list.Items {
@ -45,7 +45,7 @@ func printBackupList(list *v1.BackupList, w io.Writer, options printers.PrintOpt
return nil return nil
} }
func sortBackupsByPrefixAndTimestamp(list *v1.BackupList) { func sortBackupsByPrefixAndTimestamp(list *arkv1api.BackupList) {
// sort by default alphabetically, but if backups stem from a common schedule // sort by default alphabetically, but if backups stem from a common schedule
// (detected by the presence of a 14-digit timestamp suffix), then within that // (detected by the presence of a 14-digit timestamp suffix), then within that
// group, sort by newest to oldest (i.e. prefix ASC, suffix DESC) // group, sort by newest to oldest (i.e. prefix ASC, suffix DESC)
@ -70,7 +70,7 @@ func sortBackupsByPrefixAndTimestamp(list *v1.BackupList) {
}) })
} }
func printBackup(backup *v1.Backup, w io.Writer, options printers.PrintOptions) error { func printBackup(backup *arkv1api.Backup, w io.Writer, options printers.PrintOptions) error {
name := printers.FormatResourceName(options.Kind, backup.Name, options.WithKind) name := printers.FormatResourceName(options.Kind, backup.Name, options.WithKind)
if options.WithNamespace { if options.WithNamespace {
@ -86,13 +86,15 @@ func printBackup(backup *v1.Backup, w io.Writer, options printers.PrintOptions)
status := backup.Status.Phase status := backup.Status.Phase
if status == "" { if status == "" {
status = v1.BackupPhaseNew status = arkv1api.BackupPhaseNew
} }
if backup.DeletionTimestamp != nil && !backup.DeletionTimestamp.Time.IsZero() { if backup.DeletionTimestamp != nil && !backup.DeletionTimestamp.Time.IsZero() {
status = "Deleting" status = "Deleting"
} }
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s", name, status, backup.CreationTimestamp.Time, humanReadableTimeFromNow(expiration), metav1.FormatLabelSelector(backup.Spec.LabelSelector)); err != nil { location := backup.Spec.StorageLocation
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s", name, status, backup.CreationTimestamp.Time, humanReadableTimeFromNow(expiration), location, metav1.FormatLabelSelector(backup.Spec.LabelSelector)); err != nil {
return err return err
} }