Handle Secrets in DeleteSnapshot
This PR handles secrets at DeleteSnapshot time.
This commit is contained in:
@@ -50,7 +50,7 @@ type CSIConnection interface {
|
||||
CreateSnapshot(ctx context.Context, snapshotName string, snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (driverName string, snapshotId string, timestamp int64, status *csi.SnapshotStatus, err error)
|
||||
|
||||
// DeleteSnapshot deletes a snapshot from a volume
|
||||
DeleteSnapshot(ctx context.Context, snapshotID string) (err error)
|
||||
DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (err error)
|
||||
|
||||
// GetSnapshotStatus lists snapshot from a volume
|
||||
GetSnapshotStatus(ctx context.Context, snapshotID string) (*csi.SnapshotStatus, int64, error)
|
||||
@@ -218,12 +218,12 @@ func (c *csiConnection) CreateSnapshot(ctx context.Context, snapshotName string,
|
||||
return driverName, rsp.Snapshot.Id, rsp.Snapshot.CreatedAt, rsp.Snapshot.Status, nil
|
||||
}
|
||||
|
||||
func (c *csiConnection) DeleteSnapshot(ctx context.Context, snapshotID string) (err error) {
|
||||
func (c *csiConnection) DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) (err error) {
|
||||
client := csi.NewControllerClient(c.conn)
|
||||
|
||||
req := csi.DeleteSnapshotRequest{
|
||||
SnapshotId: snapshotID,
|
||||
DeleteSnapshotSecrets: nil,
|
||||
DeleteSnapshotSecrets: snapshotterCredentials,
|
||||
}
|
||||
|
||||
if _, err := client.DeleteSnapshot(ctx, &req); err != nil {
|
||||
|
@@ -31,7 +31,7 @@ import (
|
||||
// Handler is responsible for handling VolumeSnapshot events from informer.
|
||||
type Handler interface {
|
||||
CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, int64, *csi.SnapshotStatus, error)
|
||||
DeleteSnapshot(content *crdv1.VolumeSnapshotContent) error
|
||||
DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error
|
||||
GetSnapshotStatus(content *crdv1.VolumeSnapshotContent) (*csi.SnapshotStatus, int64, error)
|
||||
}
|
||||
|
||||
@@ -69,14 +69,14 @@ func (handler *csiHandler) CreateSnapshot(snapshot *crdv1.VolumeSnapshot, volume
|
||||
return handler.csiConnection.CreateSnapshot(ctx, snapshotName, snapshot, volume, parameters, snapshotterCredentials)
|
||||
}
|
||||
|
||||
func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent) error {
|
||||
func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent, snapshotterCredentials map[string]string) error {
|
||||
if content.Spec.CSI == nil {
|
||||
return fmt.Errorf("CSISnapshot not defined in spec")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), handler.timeout)
|
||||
defer cancel()
|
||||
|
||||
err := handler.csiConnection.DeleteSnapshot(ctx, content.Spec.CSI.SnapshotHandle)
|
||||
err := handler.csiConnection.DeleteSnapshot(ctx, content.Spec.CSI.SnapshotHandle, snapshotterCredentials)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete snapshot data %s: %q", content.Name, err)
|
||||
}
|
||||
|
@@ -483,7 +483,7 @@ func (ctrl *CSISnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
|
||||
contentName := GetSnapshotContentNameForSnapshot(snapshot)
|
||||
|
||||
// Resolve snapshotting secret credentials.
|
||||
snapshotterSecretRef, err := GetSecretReference(snapshotterSecretNameKey, snapshotterSecretNamespaceKey, class.Parameters, contentName, nil)
|
||||
snapshotterSecretRef, err := GetSecretReference(snapshotterSecretNameKey, snapshotterSecretNamespaceKey, class.Parameters, contentName, snapshot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -577,7 +577,25 @@ func (ctrl *CSISnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
|
||||
func (ctrl *CSISnapshotController) DeleteSnapshotContentOperation(content *crdv1.VolumeSnapshotContent) error {
|
||||
glog.V(4).Infof("deleteSnapshotOperation [%s] started", content.Name)
|
||||
|
||||
err := ctrl.handler.DeleteSnapshot(content)
|
||||
// get secrets if VolumeSnapshotClass specifies it
|
||||
var snapshotterCredentials map[string]string
|
||||
snapshotClassName := content.Spec.VolumeSnapshotClassName
|
||||
if len(snapshotClassName) != 0 {
|
||||
if snapshotClass, err := ctrl.clientset.VolumesnapshotV1alpha1().VolumeSnapshotClasses().Get(snapshotClassName, metav1.GetOptions{}); 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(snapshotterSecretNameKey, snapshotterSecretNamespaceKey, snapshotClass.Parameters, content.Name, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
snapshotterCredentials, err = GetCredentials(ctrl.client, snapshotterSecretRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := ctrl.handler.DeleteSnapshot(content, snapshotterCredentials)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete snapshot %#v, err: %v", content.Name, err)
|
||||
}
|
||||
|
@@ -159,10 +159,11 @@ func GetSecretReference(nameKey, namespaceKey string, snapshotClassParams map[st
|
||||
|
||||
ref := &v1.SecretReference{}
|
||||
|
||||
{
|
||||
// Secret namespace template can make use of the VolumeSnapshotContent name or the VolumeSnapshot namespace.
|
||||
// Note that neither of those things are under the control of the VolumeSnapshot user.
|
||||
namespaceParams := map[string]string{"volumesnapshotcontent.name": snapContentName}
|
||||
// snapshot may be nil when resolving create/delete snapshot secret names because the
|
||||
// snapshot may or may not exist at delete time
|
||||
if snapshot != nil {
|
||||
namespaceParams["volumesnapshot.namespace"] = snapshot.Namespace
|
||||
}
|
||||
@@ -171,6 +172,8 @@ func GetSecretReference(nameKey, namespaceKey string, snapshotClassParams map[st
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error resolving %s value %q: %v", namespaceKey, namespaceTemplate, err)
|
||||
}
|
||||
glog.V(4).Infof("GetSecretReference namespaceTemplate %s, namespaceParams: %+v, resolved %s", namespaceTemplate, namespaceParams, resolvedNamespace)
|
||||
|
||||
if len(validation.IsDNS1123Label(resolvedNamespace)) > 0 {
|
||||
if namespaceTemplate != resolvedNamespace {
|
||||
return nil, fmt.Errorf("%s parameter %q resolved to %q which is not a valid namespace name", namespaceKey, namespaceTemplate, resolvedNamespace)
|
||||
@@ -178,9 +181,7 @@ func GetSecretReference(nameKey, namespaceKey string, snapshotClassParams map[st
|
||||
return nil, fmt.Errorf("%s parameter %q is not a valid namespace name", namespaceKey, namespaceTemplate)
|
||||
}
|
||||
ref.Namespace = resolvedNamespace
|
||||
}
|
||||
|
||||
{
|
||||
// Secret name template can make use of the VolumeSnapshotContent name, VolumeSnapshot name or namespace,
|
||||
// or a VolumeSnapshot annotation.
|
||||
// Note that VolumeSnapshot name and annotations are under the VolumeSnapshot user's control.
|
||||
@@ -203,12 +204,12 @@ func GetSecretReference(nameKey, namespaceKey string, snapshotClassParams map[st
|
||||
return nil, fmt.Errorf("%s parameter %q is not a valid secret name", nameKey, nameTemplate)
|
||||
}
|
||||
ref.Name = resolvedName
|
||||
}
|
||||
|
||||
glog.V(4).Infof("GetSecretReference validated Secret: %+v", ref)
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
// resolveTemplate resolves the template by checking if the value is missing for a key
|
||||
func resolveTemplate(template string, params map[string]string) (string, error) {
|
||||
missingParams := sets.NewString()
|
||||
resolved := os.Expand(template, func(k string) string {
|
||||
@@ -224,6 +225,7 @@ func resolveTemplate(template string, params map[string]string) (string, error)
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
// GetCredentials retrieves credentials stored in v1.SecretReference
|
||||
func GetCredentials(k8s kubernetes.Interface, ref *v1.SecretReference) (map[string]string, error) {
|
||||
if ref == nil {
|
||||
return nil, nil
|
||||
|
Reference in New Issue
Block a user