Merge pull request #1337 from skriss/logs-cmd-validation

logs commands: validate item exists & is finished processing
This commit is contained in:
Nolan Brubaker
2019-04-01 15:10:52 -04:00
committed by GitHub
4 changed files with 41 additions and 45 deletions

View File

@@ -0,0 +1 @@
velero backup logs & velero restore logs: show helpful error message if backup/restore does not exist or is not finished processing

View File

@@ -21,6 +21,8 @@ import (
"time"
"github.com/spf13/cobra"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
"github.com/heptio/velero/pkg/client"
@@ -36,10 +38,24 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
Short: "Get backup logs",
Args: cobra.ExactArgs(1),
Run: func(c *cobra.Command, args []string) {
backupName := args[0]
veleroClient, err := f.Client()
cmd.CheckError(err)
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), args[0], v1.DownloadTargetKindBackupLog, os.Stdout, timeout)
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(backupName, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
cmd.Exit("Backup %q does not exist.", backupName)
} else if err != nil {
cmd.Exit("Error checking for backup %q: %v", backupName, err)
}
if backup.Status.Phase != v1.BackupPhaseCompleted && backup.Status.Phase != v1.BackupPhaseFailed {
cmd.Exit("Logs for backup %q are not available until it's finished processing. Please wait "+
"until the backup has a phase of Completed or Failed and try again.", backupName)
}
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), backupName, v1.DownloadTargetKindBackupLog, os.Stdout, timeout)
cmd.CheckError(err)
},
}

View File

@@ -20,15 +20,14 @@ import (
"os"
"time"
"github.com/pkg/errors"
"github.com/spf13/cobra"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
"github.com/heptio/velero/pkg/client"
"github.com/heptio/velero/pkg/cmd"
"github.com/heptio/velero/pkg/cmd/util/downloadrequest"
veleroclient "github.com/heptio/velero/pkg/generated/clientset/versioned"
)
func NewLogsCommand(f client.Factory) *cobra.Command {
@@ -39,12 +38,24 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
Short: "Get restore logs",
Args: cobra.ExactArgs(1),
Run: func(c *cobra.Command, args []string) {
l := NewLogsOptions()
cmd.CheckError(l.Complete(args))
cmd.CheckError(l.Validate(f))
restoreName := args[0]
veleroClient, err := f.Client()
cmd.CheckError(err)
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), args[0], v1.DownloadTargetKindRestoreLog, os.Stdout, timeout)
restore, err := veleroClient.VeleroV1().Restores(f.Namespace()).Get(restoreName, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
cmd.Exit("Restore %q does not exist.", restoreName)
} else if err != nil {
cmd.Exit("Error checking for restore %q: %v", restoreName, err)
}
if restore.Status.Phase != v1.RestorePhaseCompleted && restore.Status.Phase != v1.RestorePhaseFailed {
cmd.Exit("Logs for restore %q are not available until it's finished processing. Please wait "+
"until the restore has a phase of Completed or Failed and try again.", restoreName)
}
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), restoreName, v1.DownloadTargetKindRestoreLog, os.Stdout, timeout)
cmd.CheckError(err)
},
}
@@ -53,41 +64,3 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
return c
}
// LogsOptions contains the fields required to retrieve logs of a restore
type LogsOptions struct {
RestoreName string
client veleroclient.Interface
}
// NewLogsOptions returns a new instance of LogsOptions
func NewLogsOptions() *LogsOptions {
return &LogsOptions{}
}
// Complete fills in LogsOptions with the given parameters, like populating the
// restore name from the input args
func (l *LogsOptions) Complete(args []string) error {
l.RestoreName = args[0]
return nil
}
// Validate validates the LogsOptions against the cluster, like validating if
// the given restore exists in the cluster or not
func (l *LogsOptions) Validate(f client.Factory) error {
c, err := f.Client()
if err != nil {
return err
}
l.client = c
r, err := l.client.VeleroV1().Restores(f.Namespace()).Get(l.RestoreName, metav1.GetOptions{})
if err != nil {
return err
}
if r.Status.Phase != v1.RestorePhaseCompleted {
return errors.Errorf("unable to retrieve logs because restore is not complete")
}
return nil
}

View File

@@ -32,3 +32,9 @@ func CheckError(err error) {
os.Exit(1)
}
}
// Exit prints msg (with optional args), plus a newline, to stderr and exits with code 1.
func Exit(msg string, args ...interface{}) {
fmt.Fprintf(os.Stderr, msg+"\n", args...)
os.Exit(1)
}