From 328ba8228be910d3491129e6c783542a6f3464ee Mon Sep 17 00:00:00 2001 From: Nolan Brubaker Date: Fri, 5 Feb 2021 13:54:08 -0500 Subject: [PATCH] Add snapshot-location set command Signed-off-by: Nolan Brubaker --- pkg/cmd/cli/snapshotlocation/set.go | 116 ++++++++++++++++++ .../cli/snapshotlocation/snapshot_location.go | 1 + 2 files changed, 117 insertions(+) create mode 100644 pkg/cmd/cli/snapshotlocation/set.go diff --git a/pkg/cmd/cli/snapshotlocation/set.go b/pkg/cmd/cli/snapshotlocation/set.go new file mode 100644 index 000000000..4e35a70a6 --- /dev/null +++ b/pkg/cmd/cli/snapshotlocation/set.go @@ -0,0 +1,116 @@ +/* +Copyright The Velero contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package snapshotlocation + +import ( + "context" + "fmt" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + corev1api "k8s.io/api/core/v1" + + kbclient "sigs.k8s.io/controller-runtime/pkg/client" + + velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "github.com/vmware-tanzu/velero/pkg/client" + "github.com/vmware-tanzu/velero/pkg/cmd" + "github.com/vmware-tanzu/velero/pkg/cmd/util/flag" + "github.com/vmware-tanzu/velero/pkg/cmd/util/output" +) + +func NewSetCommand(f client.Factory, use string) *cobra.Command { + o := NewSetOptions() + + c := &cobra.Command{ + Use: use + " NAME", + Short: "Set specific features for a snapshot location", + Args: cobra.ExactArgs(1), + Run: func(c *cobra.Command, args []string) { + cmd.CheckError(o.Complete(args, f)) + cmd.CheckError(o.Validate(c, args, f)) + cmd.CheckError(o.Run(c, f)) + }, + } + + o.BindFlags(c.Flags()) + return c +} + +type SetOptions struct { + Name string + Credential flag.Map +} + +func NewSetOptions() *SetOptions { + return &SetOptions{} +} + +func (o *SetOptions) BindFlags(flags *pflag.FlagSet) { + flags.Var(&o.Credential, "credential", "Sets the credential to be used by this location as a key-value pair, where the key is the Kubernetes Secret name, and the value is the data key name within the Secret. Optional, one value only.") +} + +func (o *SetOptions) Validate(c *cobra.Command, args []string, f client.Factory) error { + if err := output.ValidateFlags(c); err != nil { + return err + } + + if len(o.Credential.Data()) > 1 { + return errors.New("--credential can only contain 1 key/value pair") + } + + return nil +} + +func (o *SetOptions) Complete(args []string, f client.Factory) error { + o.Name = args[0] + return nil +} + +func (o *SetOptions) Run(c *cobra.Command, f client.Factory) error { + kbClient, err := f.KubebuilderClient() + if err != nil { + return err + } + + location := &velerov1api.VolumeSnapshotLocation{} + err = kbClient.Get(context.Background(), kbclient.ObjectKey{ + Namespace: f.Namespace(), + Name: o.Name, + }, location) + if err != nil { + return errors.WithStack(err) + } + + for k, v := range o.Credential.Data() { + location.Spec.Credential = &corev1api.SecretKeySelector{ + LocalObjectReference: corev1api.LocalObjectReference{ + Name: k, + }, + Key: v, + } + break + } + + if err := kbClient.Update(context.Background(), location, &kbclient.UpdateOptions{}); err != nil { + return errors.WithStack(err) + } + + fmt.Printf("Volume snapshot location %q configured successfully.\n", o.Name) + return nil +} diff --git a/pkg/cmd/cli/snapshotlocation/snapshot_location.go b/pkg/cmd/cli/snapshotlocation/snapshot_location.go index e8879cd91..baebff451 100644 --- a/pkg/cmd/cli/snapshotlocation/snapshot_location.go +++ b/pkg/cmd/cli/snapshotlocation/snapshot_location.go @@ -32,6 +32,7 @@ func NewCommand(f client.Factory) *cobra.Command { c.AddCommand( NewCreateCommand(f, "create"), NewGetCommand(f, "get"), + NewSetCommand(f, "set"), ) return c