diff --git a/pkg/apis/volumesnapshot/v1alpha1/types.go b/pkg/apis/volumesnapshot/v1alpha1/types.go index a542090e9..1a06ce7fe 100644 --- a/pkg/apis/volumesnapshot/v1alpha1/types.go +++ b/pkg/apis/volumesnapshot/v1alpha1/types.go @@ -132,6 +132,11 @@ type VolumeSnapshotClass struct { // to the snapshotter. // +optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` + + // Optional: what happens to a snapshot content when released from its snapshot. + // The default policy is Delete if not specified. + // +optional + DeletionPolicy *DeletionPolicy `json:"deletionPolicy,omitempty" protobuf:"bytes,4,opt,name=deletionPolicy"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -195,6 +200,11 @@ type VolumeSnapshotContentSpec struct { // be used if it is available. // +optional VolumeSnapshotClassName *string `json:"snapshotClassName" protobuf:"bytes,4,opt,name=snapshotClassName"` + + // Optional: what happens to a snapshot content when released from its snapshot. It will be set to Delete by default + // if not specified + // +optional + DeletionPolicy *DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,5,opt,name=deletionPolicy"` } // VolumeSnapshotSource represents the actual location and type of the snapshot. Only one of its members may be specified. @@ -232,3 +242,15 @@ type CSIVolumeSnapshotSource struct { // +optional RestoreSize *int64 `json:"restoreSize,omitempty" protobuf:"bytes,4,opt,name=restoreSize"` } + +// DeletionPolicy describes a policy for end-of-life maintenance of volume snapshot contents +type DeletionPolicy string + +const ( + // VolumeSnapshotContentDelete means the snapshot content will be deleted from Kubernetes on release from its volume snapshot. + VolumeSnapshotContentDelete DeletionPolicy = "Delete" + + // VolumeSnapshotContentRetain means the snapshot will be left in its current state on release from its volume snapshot. + // The default policy is Retain if not specified. + VolumeSnapshotContentRetain DeletionPolicy = "Retain" +) \ No newline at end of file diff --git a/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshot.go b/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshot.go index 849ce8408..f383e8073 100644 --- a/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshot.go +++ b/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshot.go @@ -19,6 +19,8 @@ limitations under the License. package v1alpha1 import ( + "time" + v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -76,11 +78,16 @@ func (c *volumeSnapshots) Get(name string, options v1.GetOptions) (result *v1alp // List takes label and field selectors, and returns the list of VolumeSnapshots that match those selectors. func (c *volumeSnapshots) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } result = &v1alpha1.VolumeSnapshotList{} err = c.client.Get(). Namespace(c.ns). Resource("volumesnapshots"). VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). Do(). Into(result) return @@ -88,11 +95,16 @@ func (c *volumeSnapshots) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnap // Watch returns a watch.Interface that watches the requested volumeSnapshots. func (c *volumeSnapshots) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } opts.Watch = true return c.client.Get(). Namespace(c.ns). Resource("volumesnapshots"). VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). Watch() } @@ -150,10 +162,15 @@ func (c *volumeSnapshots) Delete(name string, options *v1.DeleteOptions) error { // DeleteCollection deletes a collection of objects. func (c *volumeSnapshots) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } return c.client.Delete(). Namespace(c.ns). Resource("volumesnapshots"). VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). Body(options). Do(). Error() diff --git a/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotclass.go b/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotclass.go index a38603165..9e48bd945 100644 --- a/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotclass.go +++ b/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotclass.go @@ -19,6 +19,8 @@ limitations under the License. package v1alpha1 import ( + "time" + v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -72,10 +74,15 @@ func (c *volumeSnapshotClasses) Get(name string, options v1.GetOptions) (result // List takes label and field selectors, and returns the list of VolumeSnapshotClasses that match those selectors. func (c *volumeSnapshotClasses) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotClassList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } result = &v1alpha1.VolumeSnapshotClassList{} err = c.client.Get(). Resource("volumesnapshotclasses"). VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). Do(). Into(result) return @@ -83,10 +90,15 @@ func (c *volumeSnapshotClasses) List(opts v1.ListOptions) (result *v1alpha1.Volu // Watch returns a watch.Interface that watches the requested volumeSnapshotClasses. func (c *volumeSnapshotClasses) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } opts.Watch = true return c.client.Get(). Resource("volumesnapshotclasses"). VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). Watch() } @@ -125,9 +137,14 @@ func (c *volumeSnapshotClasses) Delete(name string, options *v1.DeleteOptions) e // DeleteCollection deletes a collection of objects. func (c *volumeSnapshotClasses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } return c.client.Delete(). Resource("volumesnapshotclasses"). VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). Body(options). Do(). Error() diff --git a/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotcontent.go b/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotcontent.go index 9855153b9..11aac5159 100644 --- a/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotcontent.go +++ b/pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotcontent.go @@ -19,6 +19,8 @@ limitations under the License. package v1alpha1 import ( + "time" + v1alpha1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" scheme "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -72,10 +74,15 @@ func (c *volumeSnapshotContents) Get(name string, options v1.GetOptions) (result // List takes label and field selectors, and returns the list of VolumeSnapshotContents that match those selectors. func (c *volumeSnapshotContents) List(opts v1.ListOptions) (result *v1alpha1.VolumeSnapshotContentList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } result = &v1alpha1.VolumeSnapshotContentList{} err = c.client.Get(). Resource("volumesnapshotcontents"). VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). Do(). Into(result) return @@ -83,10 +90,15 @@ func (c *volumeSnapshotContents) List(opts v1.ListOptions) (result *v1alpha1.Vol // Watch returns a watch.Interface that watches the requested volumeSnapshotContents. func (c *volumeSnapshotContents) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } opts.Watch = true return c.client.Get(). Resource("volumesnapshotcontents"). VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). Watch() } @@ -125,9 +137,14 @@ func (c *volumeSnapshotContents) Delete(name string, options *v1.DeleteOptions) // DeleteCollection deletes a collection of objects. func (c *volumeSnapshotContents) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } return c.client.Delete(). Resource("volumesnapshotcontents"). VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). Body(options). Do(). Error() diff --git a/pkg/controller/csi_handler.go b/pkg/controller/csi_handler.go index d703c8e20..9cb065d47 100644 --- a/pkg/controller/csi_handler.go +++ b/pkg/controller/csi_handler.go @@ -77,7 +77,7 @@ func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent, 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) + return fmt.Errorf("failed to delete snapshot content %s: %q", content.Name, err) } return nil @@ -92,7 +92,7 @@ func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotConten csiSnapshotStatus, timestamp, size, err := handler.csiConnection.GetSnapshotStatus(ctx, content.Spec.CSI.SnapshotHandle) if err != nil { - return false, 0, 0, fmt.Errorf("failed to list snapshot data %s: %q", content.Name, err) + return false, 0, 0, fmt.Errorf("failed to list snapshot content %s: %q", content.Name, err) } return csiSnapshotStatus, timestamp, size, nil diff --git a/pkg/controller/framework_test.go b/pkg/controller/framework_test.go index 7bd2016f9..6ad800584 100644 --- a/pkg/controller/framework_test.go +++ b/pkg/controller/framework_test.go @@ -744,7 +744,7 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte } // newContent returns a new content with given attributes -func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, size *int64, creationTime *int64) *crdv1.VolumeSnapshotContent { +func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) *crdv1.VolumeSnapshotContent { content := crdv1.VolumeSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -766,6 +766,7 @@ func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToS UID: types.UID(volumeUID), Name: volumeName, }, + DeletionPolicy: deletionPolicy, }, } if boundToSnapshotName != "" { @@ -781,14 +782,14 @@ func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToS return &content } -func newContentArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent { +func newContentArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent { return []*crdv1.VolumeSnapshotContent{ - newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, size, creationTime), + newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, deletionPolicy, size, creationTime), } } -func newContentWithUnmatchDriverArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent { - content := newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, size, creationTime) +func newContentWithUnmatchDriverArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent { + content := newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, deletionPolicy, size, creationTime) content.Spec.VolumeSnapshotSource.CSI.Driver = "fake" return []*crdv1.VolumeSnapshotContent{ content, diff --git a/pkg/controller/snapshot_controller.go b/pkg/controller/snapshot_controller.go index f41b8c3d2..06cf8cb07 100644 --- a/pkg/controller/snapshot_controller.go +++ b/pkg/controller/snapshot_controller.go @@ -125,9 +125,24 @@ func (ctrl *csiSnapshotController) syncContent(content *crdv1.VolumeSnapshotCont snapshot = nil } if snapshot == nil { - ctrl.deleteSnapshotContent(content) + if content.Spec.DeletionPolicy != nil { + switch *content.Spec.DeletionPolicy { + case crdv1.VolumeSnapshotContentRetain: + glog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Retain, nothing to do", content.Name) + + case crdv1.VolumeSnapshotContentDelete: + glog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Delete", content.Name) + ctrl.deleteSnapshotContent(content) + default: + // Unknown VolumeSnapshotDeletionolicy + ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotUnknownDeletionPolicy", "Volume Snapshot Content has unrecognized deletion policy") + } + return nil + } + // By default, we use Retain policy if it is not set by users + glog.V(4).Infof("VolumeSnapshotContent[%s]: by default the policy is Retain", content.Name) + } - return nil } @@ -538,6 +553,10 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum return nil, err } + if class.DeletionPolicy == nil { + class.DeletionPolicy = new(crdv1.DeletionPolicy) + *class.DeletionPolicy = crdv1.VolumeSnapshotContentDelete + } snapshotContent := &crdv1.VolumeSnapshotContent{ ObjectMeta: metav1.ObjectMeta{ Name: contentName, @@ -554,8 +573,10 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum }, }, VolumeSnapshotClassName: &(class.Name), + DeletionPolicy: class.DeletionPolicy, }, } + glog.V(3).Infof("volume snapshot content %%v", snapshotContent) // Try to create the VolumeSnapshotContent object several times for i := 0; i < ctrl.createSnapshotContentRetryCount; i++ { glog.V(5).Infof("createSnapshot [%s]: trying to save volume snapshot content %s", snapshotKey(snapshot), snapshotContent.Name) @@ -565,7 +586,7 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum glog.V(3).Infof("volume snapshot content %q for snapshot %q already exists, reusing", snapshotContent.Name, snapshotKey(snapshot)) err = nil } else { - glog.V(3).Infof("volume snapshot content %q for snapshot %q saved", snapshotContent.Name, snapshotKey(snapshot)) + glog.V(3).Infof("volume snapshot content %q for snapshot %q saved, %v", snapshotContent.Name, snapshotKey(snapshot), snapshotContent) } break } diff --git a/pkg/controller/snapshot_controller_test.go b/pkg/controller/snapshot_controller_test.go index 1b8b17082..ab45abe87 100644 --- a/pkg/controller/snapshot_controller_test.go +++ b/pkg/controller/snapshot_controller_test.go @@ -23,7 +23,7 @@ import ( ) func storeVersion(t *testing.T, prefix string, c cache.Store, version string, expectedReturn bool) { - content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil) + content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil) content.ResourceVersion = version ret, err := storeObjectUpdate(c, content, "content") if err != nil { @@ -82,7 +82,7 @@ func TestControllerCacheParsingError(t *testing.T) { // There must be something in the cache to compare with storeVersion(t, "Step1", c, "1", true) - content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil) + content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil) content.ResourceVersion = "xxx" _, err := storeObjectUpdate(c, content, "content") if err == nil { diff --git a/pkg/controller/snapshot_create_test.go b/pkg/controller/snapshot_create_test.go index fa8b0ca81..f9083c772 100644 --- a/pkg/controller/snapshot_create_test.go +++ b/pkg/controller/snapshot_create_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1alpha1" "k8s.io/api/core/v1" storage "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -33,7 +34,8 @@ var metaTimeNowUnix = &metav1.Time{ } var defaultSize int64 = 1000 - +var deletePolicy = crdv1.VolumeSnapshotContentDelete +var retainPolicy = crdv1.VolumeSnapshotContentRetain var sameDriverStorageClass = &storage.StorageClass{ TypeMeta: metav1.TypeMeta{ Kind: "StorageClass", @@ -61,11 +63,12 @@ var diffDriverStorageClass = &storage.StorageClass{ // 2. Call the SyncSnapshot *once*. // 3. Compare resulting contents with expected contents. func TestCreateSnapshotSync(t *testing.T) { + tests := []controllerTest{ { name: "6-1 - successful create snapshot with snapshot class gold", initialContents: nocontents, - expectedContents: newContentArray("snapcontent-snapuid6-1", classGold, "sid6-1", "pv-uid6-1", "volume6-1", "snapuid6-1", "snap6-1", &defaultSize, &timeNow), + expectedContents: newContentArray("snapcontent-snapuid6-1", classGold, "sid6-1", "pv-uid6-1", "volume6-1", "snapuid6-1", "snap6-1", nil, &defaultSize, &timeNow), initialSnapshots: newSnapshotArray("snap6-1", classGold, "", "snapuid6-1", "claim6-1", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap6-1", classGold, "snapcontent-snapuid6-1", "snapuid6-1", "claim6-1", false, nil, metaTimeNowUnix, getSize(defaultSize)), initialClaims: newClaimArray("claim6-1", "pvc-uid6-1", "1Gi", "volume6-1", v1.ClaimBound, &classEmpty), @@ -89,7 +92,7 @@ func TestCreateSnapshotSync(t *testing.T) { { name: "6-2 - successful create snapshot with snapshot class silver", initialContents: nocontents, - expectedContents: newContentArray("snapcontent-snapuid6-2", classSilver, "sid6-2", "pv-uid6-2", "volume6-2", "snapuid6-2", "snap6-2", &defaultSize, &timeNow), + expectedContents: newContentArray("snapcontent-snapuid6-2", classSilver, "sid6-2", "pv-uid6-2", "volume6-2", "snapuid6-2", "snap6-2", nil, &defaultSize, &timeNow), initialSnapshots: newSnapshotArray("snap6-2", classSilver, "", "snapuid6-2", "claim6-2", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap6-2", classSilver, "snapcontent-snapuid6-2", "snapuid6-2", "claim6-2", false, nil, metaTimeNowUnix, getSize(defaultSize)), initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), @@ -113,7 +116,7 @@ func TestCreateSnapshotSync(t *testing.T) { { name: "6-3 - successful create snapshot with snapshot class valid-secret-class", initialContents: nocontents, - expectedContents: newContentArray("snapcontent-snapuid6-3", validSecretClass, "sid6-3", "pv-uid6-3", "volume6-3", "snapuid6-3", "snap6-3", &defaultSize, &timeNow), + expectedContents: newContentArray("snapcontent-snapuid6-3", validSecretClass, "sid6-3", "pv-uid6-3", "volume6-3", "snapuid6-3", "snap6-3", nil, &defaultSize, &timeNow), initialSnapshots: newSnapshotArray("snap6-3", validSecretClass, "", "snapuid6-3", "claim6-3", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap6-3", validSecretClass, "snapcontent-snapuid6-3", "snapuid6-3", "claim6-3", false, nil, metaTimeNowUnix, getSize(defaultSize)), initialClaims: newClaimArray("claim6-3", "pvc-uid6-3", "1Gi", "volume6-3", v1.ClaimBound, &classEmpty), @@ -139,7 +142,7 @@ func TestCreateSnapshotSync(t *testing.T) { { name: "6-4 - successful create snapshot with snapshot class empty-secret-class", initialContents: nocontents, - expectedContents: newContentArray("snapcontent-snapuid6-4", emptySecretClass, "sid6-4", "pv-uid6-4", "volume6-4", "snapuid6-4", "snap6-4", &defaultSize, &timeNow), + expectedContents: newContentArray("snapcontent-snapuid6-4", emptySecretClass, "sid6-4", "pv-uid6-4", "volume6-4", "snapuid6-4", "snap6-4", nil, &defaultSize, &timeNow), initialSnapshots: newSnapshotArray("snap6-4", emptySecretClass, "", "snapuid6-4", "claim6-4", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap6-4", emptySecretClass, "snapcontent-snapuid6-4", "snapuid6-4", "claim6-4", false, nil, metaTimeNowUnix, getSize(defaultSize)), initialClaims: newClaimArray("claim6-4", "pvc-uid6-4", "1Gi", "volume6-4", v1.ClaimBound, &classEmpty), @@ -165,7 +168,7 @@ func TestCreateSnapshotSync(t *testing.T) { { name: "6-5 - successful create snapshot with status uploading", initialContents: nocontents, - expectedContents: newContentArray("snapcontent-snapuid6-5", classGold, "sid6-5", "pv-uid6-5", "volume6-5", "snapuid6-5", "snap6-5", &defaultSize, &timeNow), + expectedContents: newContentArray("snapcontent-snapuid6-5", classGold, "sid6-5", "pv-uid6-5", "volume6-5", "snapuid6-5", "snap6-5", nil, &defaultSize, &timeNow), initialSnapshots: newSnapshotArray("snap6-5", classGold, "", "snapuid6-5", "claim6-5", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap6-5", classGold, "snapcontent-snapuid6-5", "snapuid6-5", "claim6-5", false, nil, metaTimeNowUnix, getSize(defaultSize)), initialClaims: newClaimArray("claim6-5", "pvc-uid6-5", "1Gi", "volume6-5", v1.ClaimBound, &classEmpty), @@ -189,7 +192,7 @@ func TestCreateSnapshotSync(t *testing.T) { { name: "6-6 - successful create snapshot with status error uploading", initialContents: nocontents, - expectedContents: newContentArray("snapcontent-snapuid6-6", classGold, "sid6-6", "pv-uid6-6", "volume6-6", "snapuid6-6", "snap6-6", &defaultSize, &timeNow), + expectedContents: newContentArray("snapcontent-snapuid6-6", classGold, "sid6-6", "pv-uid6-6", "volume6-6", "snapuid6-6", "snap6-6", nil, &defaultSize, &timeNow), initialSnapshots: newSnapshotArray("snap6-6", classGold, "", "snapuid6-6", "claim6-6", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap6-6", classGold, "snapcontent-snapuid6-6", "snapuid6-6", "claim6-6", false, nil, metaTimeNowUnix, getSize(defaultSize)), initialClaims: newClaimArray("claim6-6", "pvc-uid6-6", "1Gi", "volume6-6", v1.ClaimBound, &classEmpty), diff --git a/pkg/controller/snapshot_delete_test.go b/pkg/controller/snapshot_delete_test.go index 33e60ab19..7a3b45b31 100644 --- a/pkg/controller/snapshot_delete_test.go +++ b/pkg/controller/snapshot_delete_test.go @@ -25,6 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) + var class1Parameters = map[string]string{ "param1": "value1", } @@ -119,7 +120,7 @@ func TestDeleteSync(t *testing.T) { tests := []controllerTest{ { name: "1-1 - content with empty snapshot class is deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified", - initialContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil), + initialContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, @@ -130,8 +131,8 @@ func TestDeleteSync(t *testing.T) { }, { name: "2-1 - content with empty snapshot class will not be deleted if it is bound to a non-exist snapshot but it does not have a snapshot uid specified", - initialContents: newContentArray("content2-1", classEmpty, "sid2-1", "vuid2-1", "volume2-1", "", "snap2-1", nil, nil), - expectedContents: newContentArray("content2-1", classEmpty, "sid2-1", "vuid2-1", "volume2-1", "", "snap2-1", nil, nil), + initialContents: newContentArray("content2-1", classEmpty, "sid2-1", "vuid2-1", "volume2-1", "", "snap2-1", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-1", classEmpty, "sid2-1", "vuid2-1", "volume2-1", "", "snap2-1", &deletePolicy, nil, nil), initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, expectedEvents: noevents, @@ -141,7 +142,7 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-2 - successful delete with snapshot class that has empty secret parameter", - initialContents: newContentArray("content1-2", emptySecretClass, "sid1-2", "vuid1-2", "volume1-2", "snapuid1-2", "snap1-2", nil, nil), + initialContents: newContentArray("content1-2", emptySecretClass, "sid1-2", "vuid1-2", "volume1-2", "snapuid1-2", "snap1-2", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, @@ -153,7 +154,7 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-3 - successful delete with snapshot class that has valid secret parameter", - initialContents: newContentArray("content1-3", validSecretClass, "sid1-3", "vuid1-3", "volume1-3", "snapuid1-3", "snap1-3", nil, nil), + initialContents: newContentArray("content1-3", validSecretClass, "sid1-3", "vuid1-3", "volume1-3", "snapuid1-3", "snap1-3", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, @@ -165,8 +166,8 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-4 - fail delete with snapshot class that has invalid secret parameter", - initialContents: newContentArray("content1-4", invalidSecretClass, "sid1-4", "vuid1-4", "volume1-4", "snapuid1-4", "snap1-4", nil, nil), - expectedContents: newContentArray("content1-4", invalidSecretClass, "sid1-4", "vuid1-4", "volume1-4", "snapuid1-4", "snap1-4", nil, nil), + initialContents: newContentArray("content1-4", invalidSecretClass, "sid1-4", "vuid1-4", "volume1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil), + expectedContents: newContentArray("content1-4", invalidSecretClass, "sid1-4", "vuid1-4", "volume1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil), initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, expectedEvents: noevents, @@ -175,8 +176,8 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-5 - csi driver delete snapshot returns error", - initialContents: newContentArray("content1-5", validSecretClass, "sid1-5", "vuid1-5", "volume1-5", "snapuid1-5", "snap1-5", nil, nil), - expectedContents: newContentArray("content1-5", validSecretClass, "sid1-5", "vuid1-5", "volume1-5", "snapuid1-5", "snap1-5", nil, nil), + initialContents: newContentArray("content1-5", validSecretClass, "sid1-5", "vuid1-5", "volume1-5", "snapuid1-5", "snap1-5", &deletePolicy, nil, nil), + expectedContents: newContentArray("content1-5", validSecretClass, "sid1-5", "vuid1-5", "volume1-5", "snapuid1-5", "snap1-5", &deletePolicy, nil, nil), initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, initialSecrets: []*v1.Secret{secret()}, @@ -187,8 +188,8 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-6 - api server delete content returns error", - initialContents: newContentArray("content1-6", validSecretClass, "sid1-6", "vuid1-6", "volume1-6", "snapuid1-6", "snap1-6", nil, nil), - expectedContents: newContentArray("content1-6", validSecretClass, "sid1-6", "vuid1-6", "volume1-6", "snapuid1-6", "snap1-6", nil, nil), + initialContents: newContentArray("content1-6", validSecretClass, "sid1-6", "vuid1-6", "volume1-6", "snapuid1-6", "snap1-6", &deletePolicy, nil, nil), + expectedContents: newContentArray("content1-6", validSecretClass, "sid1-6", "vuid1-6", "volume1-6", "snapuid1-6", "snap1-6", &deletePolicy, nil, nil), initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, initialSecrets: []*v1.Secret{secret()}, @@ -205,7 +206,7 @@ func TestDeleteSync(t *testing.T) { // delete success - snapshot that the content was pointing to was deleted, and another // with the same name created. name: "1-7 - prebound content is deleted while the snapshot exists", - initialContents: newContentArray("content1-7", validSecretClass, "sid1-7", "vuid1-7", "volume1-7", "snapuid1-7", "snap1-7", nil, nil), + initialContents: newContentArray("content1-7", validSecretClass, "sid1-7", "vuid1-7", "volume1-7", "snapuid1-7", "snap1-7", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: newSnapshotArray("snap1-7", validSecretClass, "content1-7", "snapuid1-7-x", "claim1-7", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-7", validSecretClass, "content1-7", "snapuid1-7-x", "claim1-7", false, nil, nil, nil), @@ -218,7 +219,7 @@ func TestDeleteSync(t *testing.T) { { // delete success(?) - content is deleted before doDelete() starts name: "1-8 - content is deleted before deleting", - initialContents: newContentArray("content1-8", validSecretClass, "sid1-8", "vuid1-8", "volume1-8", "snapuid1-8", "snap1-8", nil, nil), + initialContents: newContentArray("content1-8", validSecretClass, "sid1-8", "vuid1-8", "volume1-8", "snapuid1-8", "snap1-8", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: nosnapshots, expectedSnapshots: nosnapshots, @@ -235,8 +236,8 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-9 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified", - initialContents: newContentArray("content1-9", validSecretClass, "sid1-9", "vuid1-9", "volume1-9", "snapuid1-9", "snap1-9", nil, nil), - expectedContents: newContentArray("content1-9", validSecretClass, "sid1-9", "vuid1-9", "volume1-9", "snapuid1-9", "snap1-9", nil, nil), + initialContents: newContentArray("content1-9", validSecretClass, "sid1-9", "vuid1-9", "volume1-9", "snapuid1-9", "snap1-9", &deletePolicy, nil, nil), + expectedContents: newContentArray("content1-9", validSecretClass, "sid1-9", "vuid1-9", "volume1-9", "snapuid1-9", "snap1-9", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap1-9", validSecretClass, "content1-9", "snapuid1-9", "claim1-9", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-9", validSecretClass, "content1-9", "snapuid1-9", "claim1-9", false, nil, nil, nil), expectedEvents: noevents, @@ -246,7 +247,7 @@ func TestDeleteSync(t *testing.T) { }, { name: "1-10 - should delete content which is bound to a snapshot incorrectly", - initialContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", nil, nil), + initialContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil), @@ -256,10 +257,21 @@ func TestDeleteSync(t *testing.T) { expectedDeleteCalls: []deleteCall{{"sid1-10", map[string]string{"foo": "bar"}, nil}}, test: testSyncContent, }, + { + name: "1-10 - will not delete content with retain policy set which is bound to a snapshot incorrectly", + initialContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", &retainPolicy, nil, nil), + expectedContents: newContentArray("content1-10", validSecretClass, "sid1-10", "vuid1-10", "volume1-10", "snapuid1-10-x", "snap1-10", &retainPolicy, nil, nil), + initialSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil), + expectedSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-10", "snapuid1-10", "claim1-10", false, nil, nil, nil), + expectedEvents: noevents, + initialSecrets: []*v1.Secret{secret()}, + errors: noerrors, + test: testSyncContent, + }, { name: "1-11 - content will not be deleted if it is bound to a snapshot correctly, snapsht uid is not specified", - initialContents: newContentArray("content1-11", validSecretClass, "sid1-11", "vuid1-11", "volume1-11", "", "snap1-11", nil, nil), - expectedContents: newContentArray("content1-11", validSecretClass, "sid1-11", "vuid1-11", "volume1-11", "", "snap1-11", nil, nil), + initialContents: newContentArray("content1-11", validSecretClass, "sid1-11", "vuid1-11", "volume1-11", "", "snap1-11", &deletePolicy, nil, nil), + expectedContents: newContentArray("content1-11", validSecretClass, "sid1-11", "vuid1-11", "volume1-11", "", "snap1-11", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap1-11", validSecretClass, "content1-11", "snapuid1-11", "claim1-11", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap1-11", validSecretClass, "content1-11", "snapuid1-11", "claim1-11", false, nil, nil, nil), expectedEvents: noevents, @@ -267,6 +279,48 @@ func TestDeleteSync(t *testing.T) { errors: noerrors, test: testSyncContent, }, + { + name: "1-12 - content with retain policy will not be deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified", + initialContents: newContentArray("content1-12", classEmpty, "sid1-12", "vuid1-12", "volume1-12", "snapuid1-12", "snap1-12", &retainPolicy, nil, nil), + expectedContents: newContentArray("content1-12", classEmpty, "sid1-12", "vuid1-12", "volume1-12", "snapuid1-12", "snap1-12", &retainPolicy, nil, nil), + initialSnapshots: nosnapshots, + expectedSnapshots: nosnapshots, + expectedEvents: noevents, + errors: noerrors, + test: testSyncContent, + }, + { + name: "1-13 - content with empty snapshot class is not deleted when Deletion policy is not set even if it is bound to a non-exist snapshot and also has a snapshot uid specified", + initialContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil), + expectedContents: newContentArray("content1-1", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil), + initialSnapshots: nosnapshots, + expectedSnapshots: nosnapshots, + expectedEvents: noevents, + errors: noerrors, + test: testSyncContent, + }, + { + name: "1-14 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified", + initialContents: newContentArray("content1-14", validSecretClass, "sid1-14", "vuid1-14", "volume1-14", "snapuid1-14", "snap1-14", &retainPolicy, nil, nil), + expectedContents: newContentArray("content1-14", validSecretClass, "sid1-14", "vuid1-14", "volume1-14", "snapuid1-14", "snap1-14", &retainPolicy, nil, nil), + initialSnapshots: newSnapshotArray("snap1-14", validSecretClass, "content1-14", "snapuid1-14", "claim1-14", false, nil, nil, nil), + expectedSnapshots: newSnapshotArray("snap1-14", validSecretClass, "content1-14", "snapuid1-14", "claim1-14", false, nil, nil, nil), + expectedEvents: noevents, + initialSecrets: []*v1.Secret{secret()}, + errors: noerrors, + test: testSyncContent, + }, + { + name: "1-15 - content will not be deleted which is bound to a snapshot incorrectly if Deletion policy is not set", + initialContents: newContentArray("content1-10", validSecretClass, "sid1-15", "vuid1-15", "volume1-15", "snapuid1-15-x", "snap1-15", nil, nil, nil), + expectedContents: newContentArray("content1-10", validSecretClass, "sid1-15", "vuid1-15", "volume1-15", "snapuid1-15-x", "snap1-15", nil, nil, nil), + initialSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-15", "snapuid1-15", "claim1-15", false, nil, nil, nil), + expectedSnapshots: newSnapshotArray("snap1-10", validSecretClass, "content1-15", "snapuid1-15", "claim1-15", false, nil, nil, nil), + expectedEvents: noevents, + initialSecrets: []*v1.Secret{secret()}, + errors: noerrors, + test: testSyncContent, + }, } runSyncTests(t, tests, snapshotClasses) } diff --git a/pkg/controller/snapshot_ready_test.go b/pkg/controller/snapshot_ready_test.go index f783517b6..e78051e9f 100644 --- a/pkg/controller/snapshot_ready_test.go +++ b/pkg/controller/snapshot_ready_test.go @@ -55,8 +55,8 @@ func TestSync(t *testing.T) { }, { name: "2-2 - could not bind snapshot and content, the VolumeSnapshotRef does not match", - initialContents: newContentArray("content2-2", validSecretClass, "sid2-2", "vuid2-2", "volume2-2", "snapuid2-2-x", "snap2-2", nil, nil), - expectedContents: newContentArray("content2-2", validSecretClass, "sid2-2", "vuid2-2", "volume2-2", "snapuid2-2-x", "snap2-2", nil, nil), + initialContents: newContentArray("content2-2", validSecretClass, "sid2-2", "vuid2-2", "volume2-2", "snapuid2-2-x", "snap2-2", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-2", validSecretClass, "sid2-2", "vuid2-2", "volume2-2", "snapuid2-2-x", "snap2-2", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-2", validSecretClass, "content2-2", "snapuid2-2", "claim2-2", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap2-2", validSecretClass, "content2-2", "snapuid2-2", "claim2-2", false, newVolumeError("Snapshot failed to bind VolumeSnapshotContent, Could not bind snapshot snap2-2 and content content2-2, the VolumeSnapshotRef does not match"), nil, nil), expectedEvents: []string{"Warning SnapshotBindFailed"}, @@ -66,8 +66,8 @@ func TestSync(t *testing.T) { /* TODO FIXME { name: "2-3 - success bind snapshot and content, no status changed", - initialContents: newContentArray("content2-3", validSecretClass, "sid2-3", "vuid2-3", "volume2-3", "", "snap2-3", nil, nil), - expectedContents: newContentArray("content2-3", validSecretClass, "sid2-3", "vuid2-3", "volume2-3", "snapuid2-3", "snap2-3", nil, nil), + initialContents: newContentArray("content2-3", validSecretClass, "sid2-3", "vuid2-3", "volume2-3", "", "snap2-3", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-3", validSecretClass, "sid2-3", "vuid2-3", "volume2-3", "snapuid2-3", "snap2-3", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-3", validSecretClass, "content2-3", "snapuid2-3", "claim2-3", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-3", validSecretClass, "content2-3", "snapuid2-3", "claim2-3", false, nil, metaTimeNow, nil), expectedListCalls: []listCall{ @@ -85,8 +85,8 @@ func TestSync(t *testing.T) { { // nothing changed name: "2-4 - noop", - initialContents: newContentArray("content2-4", validSecretClass, "sid2-4", "vuid2-4", "volume2-4", "snapuid2-4", "snap2-4", nil, nil), - expectedContents: newContentArray("content2-4", validSecretClass, "sid2-4", "vuid2-4", "volume2-4", "snapuid2-4", "snap2-4", nil, nil), + initialContents: newContentArray("content2-4", validSecretClass, "sid2-4", "vuid2-4", "volume2-4", "snapuid2-4", "snap2-4", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-4", validSecretClass, "sid2-4", "vuid2-4", "volume2-4", "snapuid2-4", "snap2-4", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-4", validSecretClass, "content2-4", "snapuid2-4", "claim2-4", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-4", validSecretClass, "content2-4", "snapuid2-4", "claim2-4", false, nil, metaTimeNow, nil), expectedListCalls: []listCall{ @@ -103,8 +103,8 @@ func TestSync(t *testing.T) { }, { name: "2-5 - snapshot and content bound, status ready false -> true", - initialContents: newContentArray("content2-5", validSecretClass, "sid2-5", "vuid2-5", "volume2-5", "snapuid2-5", "snap2-5", nil, nil), - expectedContents: newContentArray("content2-5", validSecretClass, "sid2-5", "vuid2-5", "volume2-5", "snapuid2-5", "snap2-5", nil, nil), + initialContents: newContentArray("content2-5", validSecretClass, "sid2-5", "vuid2-5", "volume2-5", "snapuid2-5", "snap2-5", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-5", validSecretClass, "sid2-5", "vuid2-5", "volume2-5", "snapuid2-5", "snap2-5", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-5", validSecretClass, "content2-5", "snapuid2-5", "claim2-5", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-5", validSecretClass, "content2-5", "snapuid2-5", "claim2-5", true, nil, metaTimeNow, nil), expectedListCalls: []listCall{ @@ -121,8 +121,8 @@ func TestSync(t *testing.T) { }, { name: "2-6 - snapshot and content bound, status -> error uploading", - initialContents: newContentArray("content2-6", validSecretClass, "sid2-6", "vuid2-6", "volume2-6", "snapuid2-6", "snap2-6", nil, nil), - expectedContents: newContentArray("content2-6", validSecretClass, "sid2-6", "vuid2-6", "volume2-6", "snapuid2-6", "snap2-6", nil, nil), + initialContents: newContentArray("content2-6", validSecretClass, "sid2-6", "vuid2-6", "volume2-6", "snapuid2-6", "snap2-6", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-6", validSecretClass, "sid2-6", "vuid2-6", "volume2-6", "snapuid2-6", "snap2-6", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", "claim2-6", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-6", validSecretClass, "content2-6", "snapuid2-6", "claim2-6", false, volumeErr, metaTimeNow, nil), expectedEvents: []string{"Warning SnapshotUploadError"}, @@ -141,8 +141,8 @@ func TestSync(t *testing.T) { */ { name: "2-7 - snapshot and content bound, csi driver get status error", - initialContents: newContentArray("content2-7", validSecretClass, "sid2-7", "vuid2-7", "volume2-7", "snapuid2-7", "snap2-7", nil, nil), - expectedContents: newContentArray("content2-7", validSecretClass, "sid2-7", "vuid2-7", "volume2-7", "snapuid2-7", "snap2-7", nil, nil), + initialContents: newContentArray("content2-7", validSecretClass, "sid2-7", "vuid2-7", "volume2-7", "snapuid2-7", "snap2-7", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-7", validSecretClass, "sid2-7", "vuid2-7", "volume2-7", "snapuid2-7", "snap2-7", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-7", validSecretClass, "content2-7", "snapuid2-7", "claim2-7", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-7", validSecretClass, "content2-7", "snapuid2-7", "claim2-7", false, newVolumeError("Failed to check and update snapshot: failed to check snapshot status snap2-7 with error failed to list snapshot data content2-7: \"mock driver get status error\""), metaTimeNow, nil), expectedEvents: []string{"Warning SnapshotCheckandUpdateFailed"}, @@ -158,8 +158,8 @@ func TestSync(t *testing.T) { /* TODO FIXME { name: "2-8 - snapshot and content bound, apiserver update status error", - initialContents: newContentArray("content2-8", validSecretClass, "sid2-8", "vuid2-8", "volume2-8", "snapuid2-8", "snap2-8", nil, nil), - expectedContents: newContentArray("content2-8", validSecretClass, "sid2-8", "vuid2-8", "volume2-8", "snapuid2-8", "snap2-8", nil, nil), + initialContents: newContentArray("content2-8", validSecretClass, "sid2-8", "vuid2-8", "volume2-8", "snapuid2-8", "snap2-8", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-8", validSecretClass, "sid2-8", "vuid2-8", "volume2-8", "snapuid2-8", "snap2-8", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-8", validSecretClass, "content2-8", "snapuid2-8", "claim2-8", false, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap2-8", validSecretClass, "content2-8", "snapuid2-8", "claim2-8", false, newVolumeError("Failed to check and update snapshot: snapshot controller failed to update default/snap2-8 on API server: mock update error"), metaTimeNow, nil), expectedEvents: []string{"Warning SnapshotUploadError"}, @@ -182,8 +182,8 @@ func TestSync(t *testing.T) { */ { name: "2-9 - bind when snapshot and content matches", - initialContents: newContentArray("content2-9", validSecretClass, "sid2-9", "vuid2-9", "volume2-9", "snapuid2-9", "snap2-9", nil, nil), - expectedContents: newContentArray("content2-9", validSecretClass, "sid2-9", "vuid2-9", "volume2-9", "snapuid2-9", "snap2-9", nil, nil), + initialContents: newContentArray("content2-9", validSecretClass, "sid2-9", "vuid2-9", "volume2-9", "snapuid2-9", "snap2-9", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-9", validSecretClass, "sid2-9", "vuid2-9", "volume2-9", "snapuid2-9", "snap2-9", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-9", validSecretClass, "", "snapuid2-9", "claim2-9", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap2-9", validSecretClass, "content2-9", "snapuid2-9", "claim2-9", false, nil, nil, nil), errors: noerrors, @@ -191,8 +191,8 @@ func TestSync(t *testing.T) { }, { name: "2-10 - do not bind when snapshot and content not match", - initialContents: newContentArray("content2-10", validSecretClass, "sid2-10", "vuid2-10", "volume2-10", "snapuid2-10-x", "snap2-10", nil, nil), - expectedContents: newContentArray("content2-10", validSecretClass, "sid2-10", "vuid2-10", "volume2-10", "snapuid2-10-x", "snap2-10", nil, nil), + initialContents: newContentArray("content2-10", validSecretClass, "sid2-10", "vuid2-10", "volume2-10", "snapuid2-10-x", "snap2-10", &deletePolicy, nil, nil), + expectedContents: newContentArray("content2-10", validSecretClass, "sid2-10", "vuid2-10", "volume2-10", "snapuid2-10-x", "snap2-10", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap2-10", validSecretClass, "", "snapuid2-10", "claim2-10", false, newVolumeError("mock driver error"), nil, nil), expectedSnapshots: newSnapshotArray("snap2-10", validSecretClass, "", "snapuid2-10", "claim2-10", false, newVolumeError("mock driver error"), nil, nil), errors: noerrors, @@ -220,8 +220,8 @@ func TestSync(t *testing.T) { }, { name: "3-3 - ready snapshot(everything is well, do nothing)", - initialContents: newContentArray("content3-3", validSecretClass, "sid3-3", "vuid3-3", "volume3-3", "snapuid3-3", "snap3-3", nil, nil), - expectedContents: newContentArray("content3-3", validSecretClass, "sid3-3", "vuid3-3", "volume3-3", "snapuid3-3", "snap3-3", nil, nil), + initialContents: newContentArray("content3-3", validSecretClass, "sid3-3", "vuid3-3", "volume3-3", "snapuid3-3", "snap3-3", &deletePolicy, nil, nil), + expectedContents: newContentArray("content3-3", validSecretClass, "sid3-3", "vuid3-3", "volume3-3", "snapuid3-3", "snap3-3", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap3-3", validSecretClass, "content3-3", "snapuid3-3", "claim3-3", true, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap3-3", validSecretClass, "content3-3", "snapuid3-3", "claim3-3", true, nil, metaTimeNow, nil), errors: noerrors, @@ -229,8 +229,8 @@ func TestSync(t *testing.T) { }, { name: "3-4 - ready snapshot misbound to VolumeSnapshotContent", - initialContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-4", nil, nil), - expectedContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-4", nil, nil), + initialContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-4", &deletePolicy, nil, nil), + expectedContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-4", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap3-4", validSecretClass, "content3-4", "snapuid3-4", "claim3-4", true, nil, metaTimeNow, nil), expectedSnapshots: newSnapshotArray("snap3-4", validSecretClass, "content3-4", "snapuid3-4", "claim3-4", false, newVolumeError("VolumeSnapshotContent is not bound to the VolumeSnapshot correctly"), metaTimeNow, nil), errors: noerrors, @@ -238,7 +238,7 @@ func TestSync(t *testing.T) { }, { name: "3-5 - snapshot bound to content in which the driver does not match", - initialContents: newContentWithUnmatchDriverArray("content3-5", validSecretClass, "sid3-5", "vuid3-5", "volume3-5", "", "snap3-5", nil, nil), + initialContents: newContentWithUnmatchDriverArray("content3-5", validSecretClass, "sid3-5", "vuid3-5", "volume3-5", "", "snap3-5", &deletePolicy, nil, nil), expectedContents: nocontents, initialSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, newVolumeError("VolumeSnapshotContent is missing"), nil, nil), @@ -248,8 +248,8 @@ func TestSync(t *testing.T) { }, { name: "3-6 - snapshot bound to content in which the snapshot uid does not match", - initialContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-6", nil, nil), - expectedContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-6", nil, nil), + initialContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-6", &deletePolicy, nil, nil), + expectedContents: newContentArray("content3-4", validSecretClass, "sid3-4", "vuid3-4", "volume3-4", "snapuid3-4-x", "snap3-6", &deletePolicy, nil, nil), initialSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, nil, nil, nil), expectedSnapshots: newSnapshotArray("snap3-5", validSecretClass, "content3-5", "snapuid3-5", "claim3-5", false, newVolumeError("VolumeSnapshotContent is missing"), nil, nil), expectedEvents: []string{"Warning SnapshotContentMissing"},