diff --git a/changelogs/unreleased/1931-Frank51 b/changelogs/unreleased/1931-Frank51 new file mode 100644 index 000000000..4a32ea841 --- /dev/null +++ b/changelogs/unreleased/1931-Frank51 @@ -0,0 +1 @@ +Add --no-default-backup-location flag to velero install diff --git a/pkg/cmd/cli/install/install.go b/pkg/cmd/cli/install/install.go index 55d7a303e..fa6dd0524 100644 --- a/pkg/cmd/cli/install/install.go +++ b/pkg/cmd/cli/install/install.go @@ -65,6 +65,7 @@ type InstallOptions struct { UseVolumeSnapshots bool DefaultResticMaintenanceFrequency time.Duration Plugins flag.StringArray + NoDefaultBackupLocation bool } // BindFlags adds command line values to the options struct. @@ -73,6 +74,7 @@ func (o *InstallOptions) BindFlags(flags *pflag.FlagSet) { flags.StringVar(&o.BucketName, "bucket", o.BucketName, "name of the object storage bucket where backups should be stored") flags.StringVar(&o.SecretFile, "secret-file", o.SecretFile, "file containing credentials for backup and volume provider. If not specified, --no-secret must be used for confirmation. Optional.") flags.BoolVar(&o.NoSecret, "no-secret", o.NoSecret, "flag indicating if a secret should be created. Must be used as confirmation if --secret-file is not provided. Optional.") + flags.BoolVar(&o.NoDefaultBackupLocation, "no-default-backup-location", o.NoDefaultBackupLocation, "flag indicating if a default backup location should be created. Must be used as confirmation if --bucket or --provider are not provided. Optional.") flags.StringVar(&o.Image, "image", o.Image, "image to use for the Velero and restic server pods. Optional.") flags.StringVar(&o.Prefix, "prefix", o.Prefix, "prefix under which all Velero data should be stored within the bucket. Optional.") flags.Var(&o.PodAnnotations, "pod-annotations", "annotations to add to the Velero and restic pods. Optional. Format is key1=value1,key2=value2") @@ -114,7 +116,8 @@ func NewInstallOptions() *InstallOptions { ResticPodCPULimit: install.DefaultResticPodCPULimit, ResticPodMemLimit: install.DefaultResticPodMemLimit, // Default to creating a VSL unless we're told otherwise - UseVolumeSnapshots: true, + UseVolumeSnapshots: true, + NoDefaultBackupLocation: false, } } @@ -158,6 +161,7 @@ func (o *InstallOptions) AsVeleroOptions() (*install.VeleroOptions, error) { VSLConfig: o.VolumeSnapshotConfig.Data(), DefaultResticMaintenanceFrequency: o.DefaultResticMaintenanceFrequency, Plugins: o.Plugins, + NoDefaultBackupLocation: o.NoDefaultBackupLocation, }, nil } @@ -264,6 +268,11 @@ func (o *InstallOptions) Run(c *cobra.Command, f client.Factory) error { if o.SecretFile == "" { fmt.Printf("\nNo secret file was specified, no Secret created.\n\n") } + + if o.NoDefaultBackupLocation { + fmt.Printf("\nNo bucket and provider were specified, no default backup storage location created.\n\n") + } + fmt.Printf("Velero is installed! ⛵ Use 'kubectl logs deployment/velero -n %s' to view the status.\n", o.Namespace) return nil } @@ -280,10 +289,6 @@ func (o *InstallOptions) Validate(c *cobra.Command, args []string, f client.Fact return err } - if o.BucketName == "" { - return errors.New("--bucket is required") - } - // Our main 3 providers don't support bucket names starting with a dash, and a bucket name starting with one // can indicate that an environment variable was left blank. // This case will help catch that error @@ -291,8 +296,44 @@ func (o *InstallOptions) Validate(c *cobra.Command, args []string, f client.Fact return errors.Errorf("Bucket names cannot begin with a dash. Bucket name was: %s", o.BucketName) } - if o.ProviderName == "" { - return errors.New("--provider is required") + if o.NoDefaultBackupLocation { + + if o.BucketName != "" { + return errors.New("Cannot use both --bucket and --no-default-backup-location at the same time") + } + + if o.Prefix != "" { + return errors.New("Cannot use both --prefix and --no-default-backup-location at the same time") + } + + if o.BackupStorageConfig.String() != "" { + return errors.New("Cannot use both --backup-location-config and --no-default-backup-location at the same time") + } + } else { + if o.ProviderName == "" { + return errors.New("--provider is required") + } + + if o.BucketName == "" { + return errors.New("--bucket is required") + } + + } + + if o.UseVolumeSnapshots { + if o.ProviderName == "" { + return errors.New("--provider is required when --use-volume-snapshots is set to true") + } + } else { + if o.VolumeSnapshotConfig.String() != "" { + return errors.New("--snapshot-location-config must be empty when --use-volume-snapshots=false") + } + } + + if o.NoDefaultBackupLocation && !o.UseVolumeSnapshots { + if o.ProviderName != "" { + return errors.New("--provider must be empty when using --no-default-backup-location and --use-volume-snapshots=false") + } } switch { diff --git a/pkg/install/resources.go b/pkg/install/resources.go index a27e5ae1c..9a0afaf47 100644 --- a/pkg/install/resources.go +++ b/pkg/install/resources.go @@ -216,6 +216,7 @@ type VeleroOptions struct { VSLConfig map[string]string DefaultResticMaintenanceFrequency time.Duration Plugins []string + NoDefaultBackupLocation bool } // AllResources returns a list of all resources necessary to install Velero, in the appropriate order, into a Kubernetes cluster. @@ -244,8 +245,10 @@ func AllResources(o *VeleroOptions) (*unstructured.UnstructuredList, error) { appendUnstructured(resources, sec) } - bsl := BackupStorageLocation(o.Namespace, o.ProviderName, o.Bucket, o.Prefix, o.BSLConfig) - appendUnstructured(resources, bsl) + if !o.NoDefaultBackupLocation { + bsl := BackupStorageLocation(o.Namespace, o.ProviderName, o.Bucket, o.Prefix, o.BSLConfig) + appendUnstructured(resources, bsl) + } // A snapshot location may not be desirable for users relying on restic if o.UseVolumeSnapshots { diff --git a/site/docs/master/install-overview.md b/site/docs/master/install-overview.md index 684d806e4..5c5706868 100644 --- a/site/docs/master/install-overview.md +++ b/site/docs/master/install-overview.md @@ -38,6 +38,8 @@ platform-agnostic backup solution for volume data. Whether you run Velero on a cloud provider or on-premises, if you have more than one volume snapshot location for a given volume provider, you can specify its default location for backups by setting a server flag in your Velero deployment YAML. +If you need to install Velero without a default backup storage location (without specifying `--bucket` or `--provider`), the `--no-default-backup-location` flag is required for confirmation. + For details, see the documentation topics for individual cloud providers. ## Installing with the Helm chart