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
parent
cf7c8587f0
commit
833a6307a9
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue