Skip to content

Commit c2593d3

Browse files
authored
Merge pull request kubernetes#88669 from mkimuram/snapfromfile
Add FromFile and FromExistingClassName support for SnapshotClass in external storage e2e test
2 parents 71cfd2a + 401b85e commit c2593d3

File tree

3 files changed

+73
-19
lines changed

3 files changed

+73
-19
lines changed

test/e2e/storage/external/external.go

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,20 @@ type driverDefinition struct {
8484
// snapshotter class with DriverInfo.Name as provisioner.
8585
FromName bool
8686

87-
// TODO (?): load from file
87+
// FromFile is used only when FromName is false. It
88+
// loads a snapshot class from the given .yaml or .json
89+
// file. File names are resolved by the
90+
// framework.testfiles package, which typically means
91+
// that they can be absolute or relative to the test
92+
// suite's --repo-root parameter.
93+
//
94+
// This can be used when the snapshot class is meant to have
95+
// additional parameters.
96+
FromFile string
97+
98+
// FromExistingClassName specifies the name of a pre-installed
99+
// SnapshotClass that will be copied and used for the tests.
100+
FromExistingClassName string
88101
}
89102

90103
// InlineVolumes defines one or more volumes for use as inline
@@ -254,7 +267,7 @@ func (d *driverDefinition) SkipUnsupportedTest(pattern testpatterns.TestPattern)
254267
case "":
255268
supported = true
256269
case testpatterns.DynamicCreatedSnapshot:
257-
if d.SnapshotClass.FromName {
270+
if d.SnapshotClass.FromName || d.SnapshotClass.FromFile != "" || d.SnapshotClass.FromExistingClassName != "" {
258271
supported = true
259272
}
260273
}
@@ -304,15 +317,53 @@ func (d *driverDefinition) GetDynamicProvisionStorageClass(config *testsuites.Pe
304317
return testsuites.GetStorageClass(sc.Provisioner, sc.Parameters, sc.VolumeBindingMode, f.Namespace.Name, "e2e-sc")
305318
}
306319

320+
func loadSnapshotClass(filename string) (*unstructured.Unstructured, error) {
321+
data, err := ioutil.ReadFile(filename)
322+
if err != nil {
323+
return nil, err
324+
}
325+
snapshotClass := &unstructured.Unstructured{}
326+
327+
if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), data, snapshotClass); err != nil {
328+
return nil, errors.Wrap(err, filename)
329+
}
330+
331+
return snapshotClass, nil
332+
}
333+
307334
func (d *driverDefinition) GetSnapshotClass(config *testsuites.PerTestConfig) *unstructured.Unstructured {
308-
if !d.SnapshotClass.FromName {
335+
if !d.SnapshotClass.FromName && d.SnapshotClass.FromFile == "" && d.SnapshotClass.FromExistingClassName == "" {
309336
e2eskipper.Skipf("Driver %q does not support snapshotting - skipping", d.DriverInfo.Name)
310337
}
311338

339+
f := config.Framework
312340
snapshotter := d.DriverInfo.Name
313341
parameters := map[string]string{}
314342
ns := config.Framework.Namespace.Name
315-
suffix := snapshotter + "-vsc"
343+
suffix := "vsc"
344+
345+
switch {
346+
case d.SnapshotClass.FromName:
347+
// Do nothing (just use empty parameters)
348+
case d.SnapshotClass.FromExistingClassName != "":
349+
snapshotClass, err := f.DynamicClient.Resource(testsuites.SnapshotClassGVR).Get(d.SnapshotClass.FromExistingClassName, metav1.GetOptions{})
350+
framework.ExpectNoError(err, "getting snapshot class %s", d.SnapshotClass.FromExistingClassName)
351+
352+
if params, ok := snapshotClass.Object["parameters"].(map[string]interface{}); ok {
353+
for k, v := range params {
354+
parameters[k] = v.(string)
355+
}
356+
}
357+
case d.SnapshotClass.FromFile != "":
358+
snapshotClass, err := loadSnapshotClass(d.SnapshotClass.FromFile)
359+
framework.ExpectNoError(err, "load snapshot class from %s", d.SnapshotClass.FromFile)
360+
361+
if params, ok := snapshotClass.Object["parameters"].(map[string]interface{}); ok {
362+
for k, v := range params {
363+
parameters[k] = v.(string)
364+
}
365+
}
366+
}
316367

317368
return testsuites.GetSnapshotClass(snapshotter, parameters, ns, suffix)
318369
}

test/e2e/storage/testsuites/provisioning.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -740,20 +740,20 @@ func prepareSnapshotDataSourceForProvisioning(
740740
volume.InjectContent(f, config, nil, "", tests)
741741

742742
ginkgo.By("[Initialize dataSource]creating a SnapshotClass")
743-
snapshotClass, err = dynamicClient.Resource(snapshotClassGVR).Create(snapshotClass, metav1.CreateOptions{})
743+
snapshotClass, err = dynamicClient.Resource(SnapshotClassGVR).Create(snapshotClass, metav1.CreateOptions{})
744744
framework.ExpectNoError(err)
745745

746746
ginkgo.By("[Initialize dataSource]creating a snapshot")
747747
snapshot := getSnapshot(updatedClaim.Name, updatedClaim.Namespace, snapshotClass.GetName())
748-
snapshot, err = dynamicClient.Resource(snapshotGVR).Namespace(updatedClaim.Namespace).Create(snapshot, metav1.CreateOptions{})
748+
snapshot, err = dynamicClient.Resource(SnapshotGVR).Namespace(updatedClaim.Namespace).Create(snapshot, metav1.CreateOptions{})
749749
framework.ExpectNoError(err)
750750

751751
WaitForSnapshotReady(dynamicClient, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, framework.SnapshotCreateTimeout)
752752
framework.ExpectNoError(err)
753753

754754
ginkgo.By("[Initialize dataSource]checking the snapshot")
755755
// Get new copy of the snapshot
756-
snapshot, err = dynamicClient.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
756+
snapshot, err = dynamicClient.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
757757
framework.ExpectNoError(err)
758758
group := "snapshot.storage.k8s.io"
759759
dataSourceRef := &v1.TypedLocalObjectReference{
@@ -764,7 +764,7 @@ func prepareSnapshotDataSourceForProvisioning(
764764

765765
cleanupFunc := func() {
766766
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
767-
err = dynamicClient.Resource(snapshotGVR).Namespace(updatedClaim.Namespace).Delete(snapshot.GetName(), nil)
767+
err = dynamicClient.Resource(SnapshotGVR).Namespace(updatedClaim.Namespace).Delete(snapshot.GetName(), nil)
768768
if err != nil && !apierrors.IsNotFound(err) {
769769
framework.Failf("Error deleting snapshot %q. Error: %v", snapshot.GetName(), err)
770770
}
@@ -776,7 +776,7 @@ func prepareSnapshotDataSourceForProvisioning(
776776
}
777777

778778
framework.Logf("deleting SnapshotClass %s", snapshotClass.GetName())
779-
framework.ExpectNoError(dynamicClient.Resource(snapshotClassGVR).Delete(snapshotClass.GetName(), nil))
779+
framework.ExpectNoError(dynamicClient.Resource(SnapshotClassGVR).Delete(snapshotClass.GetName(), nil))
780780
}
781781

782782
return dataSourceRef, cleanupFunc

test/e2e/storage/testsuites/snapshottable.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ const snapshotGroup = "snapshot.storage.k8s.io"
4242
const snapshotAPIVersion = "snapshot.storage.k8s.io/v1beta1"
4343

4444
var (
45-
snapshotGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshots"}
46-
snapshotClassGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotclasses"}
47-
snapshotContentGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotcontents"}
45+
// SnapshotGVR is GroupVersionResource for volumesnapshots
46+
SnapshotGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshots"}
47+
// SnapshotClassGVR is GroupVersionResource for volumesnapshotclasses
48+
SnapshotClassGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotclasses"}
49+
// SnapshotContentGVR is GroupVersionResource for volumesnapshotcontents
50+
SnapshotContentGVR = schema.GroupVersionResource{Group: snapshotGroup, Version: "v1beta1", Resource: "volumesnapshotcontents"}
4851
)
4952

5053
type snapshottableTestSuite struct {
@@ -167,22 +170,22 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
167170
framework.ExpectNoError(err)
168171

169172
ginkgo.By("creating a SnapshotClass")
170-
vsc, err = dc.Resource(snapshotClassGVR).Create(vsc, metav1.CreateOptions{})
173+
vsc, err = dc.Resource(SnapshotClassGVR).Create(vsc, metav1.CreateOptions{})
171174
framework.ExpectNoError(err)
172175
defer func() {
173176
framework.Logf("deleting SnapshotClass %s", vsc.GetName())
174-
framework.ExpectNoError(dc.Resource(snapshotClassGVR).Delete(vsc.GetName(), nil))
177+
framework.ExpectNoError(dc.Resource(SnapshotClassGVR).Delete(vsc.GetName(), nil))
175178
}()
176179

177180
ginkgo.By("creating a snapshot")
178181
snapshot := getSnapshot(pvc.Name, pvc.Namespace, vsc.GetName())
179182

180-
snapshot, err = dc.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Create(snapshot, metav1.CreateOptions{})
183+
snapshot, err = dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Create(snapshot, metav1.CreateOptions{})
181184
framework.ExpectNoError(err)
182185
defer func() {
183186
framework.Logf("deleting snapshot %q/%q", snapshot.GetNamespace(), snapshot.GetName())
184187
// typically this snapshot has already been deleted
185-
err = dc.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Delete(snapshot.GetName(), nil)
188+
err = dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Delete(snapshot.GetName(), nil)
186189
if err != nil && !apierrors.IsNotFound(err) {
187190
framework.Failf("Error deleting snapshot %q. Error: %v", pvc.Name, err)
188191
}
@@ -192,13 +195,13 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
192195

193196
ginkgo.By("checking the snapshot")
194197
// Get new copy of the snapshot
195-
snapshot, err = dc.Resource(snapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
198+
snapshot, err = dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Get(snapshot.GetName(), metav1.GetOptions{})
196199
framework.ExpectNoError(err)
197200

198201
// Get the bound snapshotContent
199202
snapshotStatus := snapshot.Object["status"].(map[string]interface{})
200203
snapshotContentName := snapshotStatus["boundVolumeSnapshotContentName"].(string)
201-
snapshotContent, err := dc.Resource(snapshotContentGVR).Get(snapshotContentName, metav1.GetOptions{})
204+
snapshotContent, err := dc.Resource(SnapshotContentGVR).Get(snapshotContentName, metav1.GetOptions{})
202205
framework.ExpectNoError(err)
203206

204207
snapshotContentSpec := snapshotContent.Object["spec"].(map[string]interface{})
@@ -216,7 +219,7 @@ func (s *snapshottableTestSuite) DefineTests(driver TestDriver, pattern testpatt
216219
func WaitForSnapshotReady(c dynamic.Interface, ns string, snapshotName string, Poll, timeout time.Duration) error {
217220
framework.Logf("Waiting up to %v for VolumeSnapshot %s to become ready", timeout, snapshotName)
218221
for start := time.Now(); time.Since(start) < timeout; time.Sleep(Poll) {
219-
snapshot, err := c.Resource(snapshotGVR).Namespace(ns).Get(snapshotName, metav1.GetOptions{})
222+
snapshot, err := c.Resource(SnapshotGVR).Namespace(ns).Get(snapshotName, metav1.GetOptions{})
220223
if err != nil {
221224
framework.Logf("Failed to get claim %q, retrying in %v. Error: %v", snapshotName, Poll, err)
222225
continue

0 commit comments

Comments
 (0)