When creating backup from schedule, allow default name (#2569)

* When creating backup from schedule, allow default name

Signed-off-by: Christoph Blecker <admin@toph.ca>
This commit is contained in:
Christoph Blecker
2020-05-28 12:31:25 -07:00
committed by GitHub
parent 40d8511f64
commit ceae7a2fdc
4 changed files with 35 additions and 9 deletions

View File

@@ -0,0 +1 @@
when creating new backup from schedule from cli, allow backup name to be automatically generated

View File

@@ -16,7 +16,12 @@ limitations under the License.
package v1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
import (
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ScheduleSpec defines the specification for a Velero schedule
type ScheduleSpec struct {
@@ -95,3 +100,8 @@ type ScheduleList struct {
Items []Schedule `json:"items"`
}
// TimestampedName returns the default backup name format based on the schedule
func (s *Schedule) TimestampedName(timestamp time.Time) string {
return fmt.Sprintf("%s-%s", s.Name, timestamp.Format("20060102150405"))
}

View File

@@ -43,7 +43,7 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
c := &cobra.Command{
Use: use + " NAME",
Short: "Create a backup",
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
Run: func(c *cobra.Command, args []string) {
cmd.CheckError(o.Complete(args, f))
cmd.CheckError(o.Validate(c, args, f))
@@ -58,9 +58,12 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
# create a backup excluding the velero and default namespaces
velero backup create backup2 --exclude-namespaces velero,default
# create a backup based on a schedule named daily-backup
velero backup create --from-schedule daily-backup
# view the YAML for a backup that doesn't snapshot volumes, without sending it to the server
velero backup create backup3 --snapshot-volumes=false -o yaml
# wait for a backup to complete before returning from the command
velero backup create backup4 --wait`,
}
@@ -131,7 +134,7 @@ func (o *CreateOptions) BindWait(flags *pflag.FlagSet) {
// BindFromSchedule binds the from-schedule flag separately so it is not called
// by other create commands that reuse CreateOptions's BindFlags method.
func (o *CreateOptions) BindFromSchedule(flags *pflag.FlagSet) {
flags.StringVar(&o.FromSchedule, "from-schedule", "", "create a backup from the template of an existing schedule. Cannot be used with any other filters.")
flags.StringVar(&o.FromSchedule, "from-schedule", "", "create a backup from the template of an existing schedule. Cannot be used with any other filters. Backup name is optional if used.")
}
func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Factory) error {
@@ -139,6 +142,11 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
return err
}
// Ensure that unless FromSchedule is set, args contains a backup name
if o.FromSchedule == "" && len(args) != 1 {
return fmt.Errorf("a backup name is required, unless you are creating based on a schedule")
}
if o.StorageLocation != "" {
if _, err := o.client.VeleroV1().BackupStorageLocations(f.Namespace()).Get(o.StorageLocation, metav1.GetOptions{}); err != nil {
return err
@@ -155,7 +163,10 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
}
func (o *CreateOptions) Complete(args []string, f client.Factory) error {
o.Name = args[0]
// If an explict name is specified, use that name
if len(args) > 0 {
o.Name = args[0]
}
client, err := f.Client()
if err != nil {
return err
@@ -255,16 +266,20 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
}
func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, error) {
backupBuilder := builder.ForBackup(namespace, o.Name)
var backupBuilder *builder.BackupBuilder
if o.FromSchedule != "" {
schedule, err := o.client.VeleroV1().Schedules(namespace).Get(o.FromSchedule, metav1.GetOptions{})
if err != nil {
return nil, err
}
backupBuilder.FromSchedule(schedule)
if o.Name == "" {
o.Name = schedule.TimestampedName(time.Now())
}
backupBuilder = builder.ForBackup(namespace, o.Name).
FromSchedule(schedule)
} else {
backupBuilder.
backupBuilder = builder.ForBackup(namespace, o.Name).
IncludedNamespaces(o.IncludeNamespaces...).
ExcludedNamespaces(o.ExcludeNamespaces...).
IncludedResources(o.IncludeResources...).

View File

@@ -288,7 +288,7 @@ func getNextRunTime(schedule *api.Schedule, cronSchedule cron.Schedule, asOf tim
}
func getBackup(item *api.Schedule, timestamp time.Time) *api.Backup {
name := fmt.Sprintf("%s-%s", item.Name, timestamp.Format("20060102150405"))
name := item.TimestampedName(timestamp)
backup := builder.
ForBackup(item.Namespace, name).
FromSchedule(item).