commit
3070feaeb2
|
@ -0,0 +1,2 @@
|
|||
Add Credential field to Volume Snapshot Locations for multiple credential support.
|
||||
Add `velero snapshot-location set` command to edit credentials on a Volume Snapshot Location.
|
|
@ -50,6 +50,24 @@ spec:
|
|||
type: string
|
||||
description: Config is for provider-specific configuration fields.
|
||||
type: object
|
||||
credential:
|
||||
description: Credential contains the credential information intended
|
||||
to be used with this location
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must be a valid
|
||||
secret key.
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
TODO: Add other useful fields. apiVersion, kind, uid?'
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
provider:
|
||||
description: Provider is the provider of the volume storage.
|
||||
type: string
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -16,7 +16,10 @@ limitations under the License.
|
|||
|
||||
package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
import (
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
@ -57,6 +60,10 @@ type VolumeSnapshotLocationSpec struct {
|
|||
// Config is for provider-specific configuration fields.
|
||||
// +optional
|
||||
Config map[string]string `json:"config,omitempty"`
|
||||
|
||||
// Credential contains the credential information intended to be used with this location
|
||||
// +optional
|
||||
Credential *corev1api.SecretKeySelector `json:"credential,omitempty"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotLocationPhase is the lifecycle phase of a Velero VolumeSnapshotLocation.
|
||||
|
|
|
@ -1632,6 +1632,11 @@ func (in *VolumeSnapshotLocationSpec) DeepCopyInto(out *VolumeSnapshotLocationSp
|
|||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Credential != nil {
|
||||
in, out := &in.Credential, &out.Credential
|
||||
*out = new(corev1.SecretKeySelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
|
@ -54,15 +56,19 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
|
|||
}
|
||||
|
||||
type CreateOptions struct {
|
||||
Name string
|
||||
Provider string
|
||||
Config flag.Map
|
||||
Labels flag.Map
|
||||
Name string
|
||||
Provider string
|
||||
Config flag.Map
|
||||
Labels flag.Map
|
||||
Credential flag.Map
|
||||
secretName string
|
||||
secretKey string
|
||||
}
|
||||
|
||||
func NewCreateOptions() *CreateOptions {
|
||||
return &CreateOptions{
|
||||
Config: flag.NewMap(),
|
||||
Config: flag.NewMap(),
|
||||
Credential: flag.NewMap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +76,7 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) {
|
|||
flags.StringVar(&o.Provider, "provider", o.Provider, "Name of the volume snapshot provider (e.g. aws, azure, gcp).")
|
||||
flags.Var(&o.Config, "config", "Configuration key-value pairs.")
|
||||
flags.Var(&o.Labels, "labels", "Labels to apply to the volume snapshot location.")
|
||||
flags.Var(&o.Credential, "credential", "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 *CreateOptions) Validate(c *cobra.Command, args []string, f client.Factory) error {
|
||||
|
@ -81,6 +88,15 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
|
|||
return errors.New("--provider is required")
|
||||
}
|
||||
|
||||
if len(o.Credential.Data()) > 1 {
|
||||
return errors.New("--credential can only contain 1 key/value pair")
|
||||
}
|
||||
|
||||
for k, v := range o.Credential.Data() {
|
||||
o.secretName = k
|
||||
o.secretKey = v
|
||||
break
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -99,6 +115,12 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
|
|||
Spec: api.VolumeSnapshotLocationSpec{
|
||||
Provider: o.Provider,
|
||||
Config: o.Config.Data(),
|
||||
Credential: &corev1api.SecretKeySelector{
|
||||
LocalObjectReference: corev1api.LocalObjectReference{
|
||||
Name: o.secretName,
|
||||
},
|
||||
Key: o.secretKey,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
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{
|
||||
Credential: flag.NewMap(),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
|
@ -32,6 +32,7 @@ func NewCommand(f client.Factory) *cobra.Command {
|
|||
c.AddCommand(
|
||||
NewCreateCommand(f, "create"),
|
||||
NewGetCommand(f, "get"),
|
||||
NewSetCommand(f, "set"),
|
||||
)
|
||||
|
||||
return c
|
||||
|
|
Loading…
Reference in New Issue