Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add secret for ListSnapshot call #162

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkg/controller/csi_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
type Handler interface {
CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error)
DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error
GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, time.Time, int64, error)
GetSnapshotStatus(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) (bool, time.Time, int64, error)
}

// csiHandler is a handler that calls CSI to create/delete volume snapshot.
Expand Down Expand Up @@ -89,14 +89,14 @@ func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent,
return nil
}

func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (bool, time.Time, int64, error) {
func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) (bool, time.Time, int64, error) {
if content.Spec.CSI == nil {
return false, time.Time{}, 0, fmt.Errorf("CSISnapshot not defined in spec")
}
ctx, cancel := context.WithTimeout(context.Background(), handler.timeout)
defer cancel()

csiSnapshotStatus, timestamp, size, err := handler.snapshotter.GetSnapshotStatus(ctx, content.Spec.CSI.SnapshotHandle)
csiSnapshotStatus, timestamp, size, err := handler.snapshotter.GetSnapshotStatus(ctx, content.Spec.CSI.SnapshotHandle, snapshotterCredentials)
if err != nil {
return false, time.Time{}, 0, fmt.Errorf("failed to list snapshot content %s: %q", content.Name, err)
}
Expand Down
27 changes: 24 additions & 3 deletions pkg/controller/snapshot_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ func (ctrl *csiSnapshotController) getCreateSnapshotInput(snapshot *crdv1.Volume
contentName := GetSnapshotContentNameForSnapshot(snapshot)

// Resolve snapshotting secret credentials.
snapshotterSecretRef, err := getSecretReference(class.Parameters, contentName, snapshot)
snapshotterSecretRef, err := getSecretReference(class.Parameters, snapshotterSecretParams, contentName, snapshot)
if err != nil {
return nil, nil, "", nil, err
}
Expand All @@ -561,6 +561,22 @@ func (ctrl *csiSnapshotController) getCreateSnapshotInput(snapshot *crdv1.Volume
return class, volume, contentName, snapshotterCredentials, nil
}

func (ctrl *csiSnapshotController) getListSnapshotCredentials(snapshot *crdv1.VolumeSnapshot) (map[string]string, error) {
className := snapshot.Spec.VolumeSnapshotClassName
if className == nil {
return nil, fmt.Errorf("failed to get list snapshot credentials for %s without a snapshot class", snapshot.Name)
}
vsc, err := ctrl.clientset.SnapshotV1alpha1().VolumeSnapshotClasses().Get(className, metav1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("failed to get the snapshot class %s: Error: [%#v]", className, err)
}
secretRef, err := getSecretReference(vsc.Parameters, snapshotterListSecretParams, snapshot.Spec.SnapshotContentName)
if err != nil {
return nil, fmt.Errorf("failed to get secret reference for list operation")
}
return getCredentials(ctrl.client, secretRef)
}

func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(snapshot *crdv1.VolumeSnapshot, content *crdv1.VolumeSnapshotContent) (*crdv1.VolumeSnapshot, error) {
var err error
var creationTime time.Time
Expand All @@ -570,8 +586,13 @@ func (ctrl *csiSnapshotController) checkandUpdateBoundSnapshotStatusOperation(sn
var snapshotID string

if snapshot.Spec.Source == nil {
snapshotterListCredentials, err := ctrl.getListSnapshotCredentials(snapshot)
if err != nil {
klog.Errorf("checkAndUpdateBoundSnapshotStatusOperation: failed to get list snapshot credentials from snapshot [%s", snapshot.Name)
return nil, err
}
klog.V(5).Infof("checkandUpdateBoundSnapshotStatusOperation: checking whether snapshot [%s] is pre-bound to content [%s]", snapshot.Name, content.Name)
readyToUse, creationTime, size, err = ctrl.handler.GetSnapshotStatus(content)
readyToUse, creationTime, size, err = ctrl.handler.GetSnapshotStatus(content, snapshotterListCredentials)
if err != nil {
klog.Errorf("checkandUpdateBoundSnapshotStatusOperation: failed to call get snapshot status to check whether snapshot is ready to use %q", err)
return nil, err
Expand Down Expand Up @@ -741,7 +762,7 @@ func (ctrl *csiSnapshotController) deleteSnapshotContentOperation(content *crdv1
if snapshotClass, err := ctrl.classLister.Get(*snapshotClassName); err == nil {
// Resolve snapshotting secret credentials.
// No VolumeSnapshot is provided when resolving delete secret names, since the VolumeSnapshot may or may not exist at delete time.
snapshotterSecretRef, err := getSecretReference(snapshotClass.Parameters, content.Name, nil)
snapshotterSecretRef, err := getSecretReference(snapshotClass.Parameters, snapshotterSecretParams, content.Name, nil)
if err != nil {
return err
}
Expand Down
21 changes: 15 additions & 6 deletions pkg/controller/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ package controller

import (
"fmt"
"os"
"strconv"
"strings"
"time"

crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1"
"k8s.io/api/core/v1"
Expand All @@ -30,9 +33,6 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/util/slice"
"os"
"strconv"
"time"
)

var (
Expand All @@ -57,6 +57,9 @@ const (
prefixedSnapshotterSecretNameKey = csiParameterPrefix + "snapshotter-secret-name"
prefixedSnapshotterSecretNamespaceKey = csiParameterPrefix + "snapshotter-secret-namespace"

listSnapshotSecretNameKey = csiParameterPrefix + "snapshotter-list-snapshot-secret-name"
listSnapshotSecretNamespaceKey = csiParameterPrefix + "snapshotter-list-snapshot-secret-namespace"

// [Deprecated] CSI Parameters that are put into fields but
// NOT stripped from the parameters passed to CreateSnapshot
snapshotterSecretNameKey = "csiSnapshotterSecretName"
Expand All @@ -68,13 +71,19 @@ const (
)

var snapshotterSecretParams = deprecatedSecretParamsMap{
name: "Snapshotter",
name: "Snapshotter (CreateSnapshot, DeleteSnapshot)",
deprecatedSecretNameKey: snapshotterSecretNameKey,
deprecatedSecretNamespaceKey: snapshotterSecretNamespaceKey,
secretNameKey: prefixedSnapshotterSecretNameKey,
secretNamespaceKey: prefixedSnapshotterSecretNamespaceKey,
}

var snapshotterListSecretParams = deprecatedSecretParamsMap{
name: "Snapshotter (ListSnapshot)",
secretNameKey: listSnapshotSecretNameKey,
secretNamespaceKey: listSnapshotSecretNamespaceKey,
}

// Name of finalizer on PVCs that have been used as a source to create VolumeSnapshots
const PVCFinalizer = "snapshot.storage.kubernetes.io/pvc-protection"

Expand Down Expand Up @@ -227,8 +236,8 @@ func verifyAndGetSecretNameAndNamespaceTemplate(secret deprecatedSecretParamsMap
// - the nameTemplate or namespaceTemplate contains a token that cannot be resolved
// - the resolved name is not a valid secret name
// - the resolved namespace is not a valid namespace name
func getSecretReference(snapshotClassParams map[string]string, snapContentName string, snapshot *crdv1.VolumeSnapshot) (*v1.SecretReference, error) {
nameTemplate, namespaceTemplate, err := verifyAndGetSecretNameAndNamespaceTemplate(snapshotterSecretParams, snapshotClassParams)
func getSecretReference(snapshotClassParams map[string]string, secretMap deprecatedSecretParamsMap, snapContentName string, snapshot *crdv1.VolumeSnapshot) (*v1.SecretReference, error) {
nameTemplate, namespaceTemplate, err := verifyAndGetSecretNameAndNamespaceTemplate(secretMap, snapshotClassParams)
if err != nil {
return nil, fmt.Errorf("failed to get name and namespace template from params: %v", err)
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/snapshotter/snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ import (
"github.com/container-storage-interface/spec/lib/go/csi"
"github.com/golang/protobuf/ptypes"
csirpc "github.com/kubernetes-csi/csi-lib-utils/rpc"

"google.golang.org/grpc"

"k8s.io/api/core/v1"
"k8s.io/klog"
)
Expand All @@ -40,7 +38,7 @@ type Snapshotter interface {
DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (err error)

// GetSnapshotStatus returns if a snapshot is ready to use, creation time, and restore size.
GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, time.Time, int64, error)
GetSnapshotStatus(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (bool, time.Time, int64, error)
}

type snapshot struct {
Expand Down Expand Up @@ -117,7 +115,7 @@ func (s *snapshot) isListSnapshotsSupported(ctx context.Context) (bool, error) {
return false, nil
}

func (s *snapshot) GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, time.Time, int64, error) {
func (s *snapshot) GetSnapshotStatus(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (bool, time.Time, int64, error) {
client := csi.NewControllerClient(s.conn)

// If the driver does not support ListSnapshots, assume the snapshot ID is valid.
Expand All @@ -130,6 +128,7 @@ func (s *snapshot) GetSnapshotStatus(ctx context.Context, snapshotID string) (bo
}
req := csi.ListSnapshotsRequest{
SnapshotId: snapshotID,
Secrets: snapshotterCredentials,
}
rsp, err := client.ListSnapshots(ctx, &req)
if err != nil {
Expand Down