Merge pull request #3409 from nrb/add-credentials-to-vsls

Add credentials to VSLs
pull/3441/head
JenTing Hsiao 2021-02-10 09:07:41 +08:00 committed by GitHub
commit 3070feaeb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 180 additions and 7 deletions

2
changelogs/3409-nrb Normal file
View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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
}

View File

@ -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,
},
},
}

View File

@ -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
}

View File

@ -32,6 +32,7 @@ func NewCommand(f client.Factory) *cobra.Command {
c.AddCommand(
NewCreateCommand(f, "create"),
NewGetCommand(f, "get"),
NewSetCommand(f, "set"),
)
return c