Skip to content

Commit 60b7226

Browse files
committed
Check idempotence with API Error
1 parent 5fc92a3 commit 60b7226

File tree

4 files changed

+145
-0
lines changed

4 files changed

+145
-0
lines changed

pkg/cloud/cloud.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ func (c *cloud) DeleteDisk(ctx context.Context, volumeID string) (bool, error) {
458458
return false, nil
459459
}
460460
}
461+
if isVolumeNotFoundError(err) {
462+
return false, ErrNotFound
463+
}
461464
return false, fmt.Errorf("DeleteDisk could not delete volume in Outscale: %v", err)
462465
}
463466
return true, nil
@@ -805,6 +808,9 @@ func (c *cloud) DeleteSnapshot(ctx context.Context, snapshotID string) (success
805808
return false, nil
806809
}
807810
}
811+
if isSnapshotNotFoundError(err) {
812+
return false, ErrNotFound
813+
}
808814
return false, fmt.Errorf("DeleteSnapshot could not delete volume: %v", err)
809815
}
810816
return true, nil

pkg/cloud/utils.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package cloud
2+
3+
import osc "github.com/outscale/osc-sdk-go/v2"
4+
5+
func extractError(err error) (bool, *osc.ErrorResponse) {
6+
genericError, ok := err.(osc.GenericOpenAPIError)
7+
if ok {
8+
errorsResponse, ok := genericError.Model().(osc.ErrorResponse)
9+
if ok {
10+
return true, &errorsResponse
11+
}
12+
return false, nil
13+
}
14+
return false, nil
15+
}
16+
17+
func isVolumeNotFoundError(err error) bool {
18+
if ok, apirErr := extractError(err); ok {
19+
if apirErr.GetErrors()[0].GetType() == "InvalidResource" && apirErr.GetErrors()[0].GetCode() == "5064" {
20+
return true
21+
}
22+
}
23+
return false
24+
}
25+
26+
func isSnapshotNotFoundError(err error) bool {
27+
if ok, apirErr := extractError(err); ok {
28+
if apirErr.GetErrors()[0].GetType() == "InvalidResource" && apirErr.GetErrors()[0].GetCode() == "5054" {
29+
return true
30+
}
31+
}
32+
return false
33+
}

tests/e2e/dynamic_provisioning.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ limitations under the License.
1515
package e2e
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"log"
2021
"math/rand"
2122
"os"
2223
"strings"
24+
"time"
2325

2426
. "github.com/onsi/ginkgo"
2527
v1 "k8s.io/api/core/v1"
@@ -31,13 +33,16 @@ import (
3133
"github.com/outscale-dev/osc-bsu-csi-driver/tests/e2e/driver"
3234
"github.com/outscale-dev/osc-bsu-csi-driver/tests/e2e/testsuites"
3335

36+
"github.com/outscale-dev/osc-bsu-csi-driver/pkg/cloud"
3437
osccloud "github.com/outscale-dev/osc-bsu-csi-driver/pkg/cloud"
3538
bsucsidriver "github.com/outscale-dev/osc-bsu-csi-driver/pkg/driver"
3639
"k8s.io/apimachinery/pkg/runtime"
3740
"k8s.io/apimachinery/pkg/runtime/schema"
3841
"k8s.io/apimachinery/pkg/runtime/serializer"
3942
)
4043

44+
const OSC_REGION = "OSC_REGION"
45+
4146
var _ = Describe("[bsu-csi-e2e] [single-az] Dynamic Provisioning", func() {
4247
f := framework.NewDefaultFramework("bsu")
4348

@@ -539,6 +544,49 @@ var _ = Describe("[bsu-csi-e2e] [single-az] Dynamic Provisioning", func() {
539544

540545
test.Run(cs, ns, f)
541546
})
547+
548+
It("should create a volume, delete it from outside and release the volume", func() {
549+
binding := storagev1.VolumeBindingImmediate
550+
retain := v1.PersistentVolumeReclaimDelete
551+
volume := testsuites.VolumeDetails{
552+
VolumeType: osccloud.VolumeTypeGP2,
553+
FSType: bsucsidriver.FSTypeExt4,
554+
ClaimSize: driver.MinimumSizeForVolumeType(osccloud.VolumeTypeGP2),
555+
VolumeBindingMode: &binding,
556+
ReclaimPolicy: &retain,
557+
}
558+
559+
By("Create the PVC")
560+
tpvc, cleanups := volume.SetupDynamicPersistentVolumeClaim(cs, ns, bsuDriver)
561+
for i := range cleanups {
562+
defer cleanups[i]()
563+
}
564+
565+
tpvc.WaitForBound()
566+
567+
if os.Getenv(OSC_REGION) == "" {
568+
Skip(fmt.Sprintf("env %q not set", OSC_REGION))
569+
}
570+
571+
By("Create the cloud")
572+
573+
oscCloud, err := osccloud.NewCloudWithoutMetadata(os.Getenv(OSC_REGION))
574+
framework.ExpectNoError(err, "Error while creating a cloud configuration")
575+
576+
By("Keep delete the disk until error")
577+
tpvc.DeleteBackingVolume(oscCloud)
578+
579+
pv := tpvc.GetPersistentVolume()
580+
for i := 1; i < 100; i++ {
581+
_, err := oscCloud.DeleteDisk(context.Background(), pv.Spec.CSI.VolumeHandle)
582+
if err == cloud.ErrNotFound {
583+
break
584+
}
585+
fmt.Println("Disk still present, waiting")
586+
time.Sleep(1 * time.Second)
587+
}
588+
589+
})
542590
})
543591

544592
var _ = Describe("[bsu-csi-e2e] [single-az] Snapshot", func() {
@@ -599,6 +647,60 @@ var _ = Describe("[bsu-csi-e2e] [single-az] Snapshot", func() {
599647
}
600648
test.Run(cs, snapshotrcs, ns)
601649
})
650+
651+
It("should create a snapshot, delete it from outside and release the snapshot", func() {
652+
binding := storagev1.VolumeBindingImmediate
653+
retain := v1.PersistentVolumeReclaimDelete
654+
volume := testsuites.VolumeDetails{
655+
VolumeType: osccloud.VolumeTypeGP2,
656+
FSType: bsucsidriver.FSTypeExt4,
657+
ClaimSize: driver.MinimumSizeForVolumeType(osccloud.VolumeTypeGP2),
658+
VolumeBindingMode: &binding,
659+
ReclaimPolicy: &retain,
660+
}
661+
662+
By("Create the PVC")
663+
tpvc, cleanups := volume.SetupDynamicPersistentVolumeClaim(cs, ns, bsuDriver)
664+
for i := range cleanups {
665+
defer cleanups[i]()
666+
}
667+
668+
pvc := tpvc.WaitForBound()
669+
670+
if os.Getenv(OSC_REGION) == "" {
671+
Skip(fmt.Sprintf("env %q not set", OSC_REGION))
672+
}
673+
674+
By("Create the Snapshot")
675+
tvsc, cleanup := testsuites.CreateVolumeSnapshotClass(snapshotrcs, ns, bsuDriver)
676+
defer cleanup()
677+
snapshot := tvsc.CreateSnapshot(&pvc)
678+
defer tvsc.DeleteSnapshot(snapshot)
679+
tvsc.ReadyToUse(snapshot)
680+
681+
By("Create the cloud")
682+
oscCloud, err := osccloud.NewCloudWithoutMetadata(os.Getenv(OSC_REGION))
683+
framework.ExpectNoError(err, "Error while creating a cloud configuration")
684+
685+
By("Retrieve the snapshot")
686+
snap, err := oscCloud.GetSnapshotByName(context.Background(), fmt.Sprintf("snapshot-%v", snapshot.UID))
687+
framework.ExpectNoError(err, fmt.Sprintf("Error while retrieving snapshot %v", snapshot.UID))
688+
689+
By("Deleting the snapshot")
690+
_, err = oscCloud.DeleteSnapshot(context.Background(), snap.SnapshotID)
691+
framework.ExpectNoError(err, fmt.Sprintf("Error while deleting snapshot %v", snap.SnapshotID))
692+
693+
By("Keep deleting the snapshot until error")
694+
for i := 1; i < 100; i++ {
695+
_, err := oscCloud.DeleteSnapshot(context.Background(), snap.SnapshotID)
696+
if err == cloud.ErrNotFound {
697+
break
698+
}
699+
fmt.Println("Snapshot still present, waiting")
700+
time.Sleep(1 * time.Second)
701+
}
702+
703+
})
602704
})
603705

604706
var _ = Describe("[bsu-csi-e2e] [multi-az] Dynamic Provisioning", func() {

tests/e2e/testsuites/testsuites.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ func (t *TestPersistentVolumeClaim) DeleteBackingVolume(cloud osccloud.Cloud) {
372372
}
373373
}
374374

375+
func (t *TestPersistentVolumeClaim) GetPersistentVolume() *v1.PersistentVolume {
376+
return t.persistentVolume
377+
}
378+
375379
type TestDeployment struct {
376380
client clientset.Interface
377381
deployment *apps.Deployment

0 commit comments

Comments
 (0)