mirror of
https://github.com/kubevirt/containerized-data-importer.git
synced 2025-06-03 06:30:22 +00:00

* Default virt storage class Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com> * Add alert for multiple default virt storage classes Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com> * Refactor content type funcs to not return strings Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com> --------- Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com>
249 lines
8.6 KiB
Go
249 lines
8.6 KiB
Go
package common
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
v1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
|
|
)
|
|
|
|
var _ = Describe("GetRequestedImageSize", func() {
|
|
It("Should return 1G if 1G provided", func() {
|
|
result, err := GetRequestedImageSize(CreatePvc("testPVC", "default", nil, nil))
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(result).To(Equal("1G"))
|
|
})
|
|
|
|
It("Should return error and blank if no size provided", func() {
|
|
result, err := GetRequestedImageSize(createPvcNoSize("testPVC", "default", nil, nil))
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(result).To(Equal(""))
|
|
})
|
|
})
|
|
|
|
var _ = Describe("validateContentTypes", func() {
|
|
getContentType := func(contentType string) cdiv1.DataVolumeContentType {
|
|
if contentType == "" {
|
|
return cdiv1.DataVolumeKubeVirt
|
|
}
|
|
return cdiv1.DataVolumeContentType(contentType)
|
|
}
|
|
|
|
DescribeTable("should return", func(sourceContentType, targetContentType string, expectedResult bool) {
|
|
sourcePvc := CreatePvc("testPVC", "default", map[string]string{AnnContentType: sourceContentType}, nil)
|
|
dvSpec := &cdiv1.DataVolumeSpec{}
|
|
dvSpec.ContentType = cdiv1.DataVolumeContentType(targetContentType)
|
|
|
|
validated, sourceContent, targetContent := validateContentTypes(sourcePvc, dvSpec)
|
|
Expect(validated).To(Equal(expectedResult))
|
|
Expect(sourceContent).To(Equal(getContentType(sourceContentType)))
|
|
Expect(targetContent).To(Equal(getContentType(targetContentType)))
|
|
},
|
|
Entry("true when using archive in source and target", string(cdiv1.DataVolumeArchive), string(cdiv1.DataVolumeArchive), true),
|
|
Entry("false when using archive in source and KubeVirt in target", string(cdiv1.DataVolumeArchive), string(cdiv1.DataVolumeKubeVirt), false),
|
|
Entry("false when using KubeVirt in source and archive in target", string(cdiv1.DataVolumeKubeVirt), string(cdiv1.DataVolumeArchive), false),
|
|
Entry("true when using KubeVirt in source and target", string(cdiv1.DataVolumeKubeVirt), string(cdiv1.DataVolumeKubeVirt), true),
|
|
Entry("true when using default in source and target", "", "", true),
|
|
Entry("true when using default in source and KubeVirt (explicit) in target", "", string(cdiv1.DataVolumeKubeVirt), true),
|
|
Entry("true when using KubeVirt (explicit) in source and default in target", string(cdiv1.DataVolumeKubeVirt), "", true),
|
|
Entry("false when using default in source and archive in target", "", string(cdiv1.DataVolumeArchive), false),
|
|
Entry("false when using archive in source and default in target", string(cdiv1.DataVolumeArchive), "", false),
|
|
)
|
|
})
|
|
|
|
var _ = Describe("GetStorageClassByName", func() {
|
|
It("Should return the default storage class name", func() {
|
|
client := CreateClient(
|
|
CreateStorageClass("test-storage-class-1", nil),
|
|
CreateStorageClass("test-storage-class-2", map[string]string{
|
|
AnnDefaultStorageClass: "true",
|
|
}),
|
|
)
|
|
sc, _ := GetStorageClassByNameWithK8sFallback(context.Background(), client, nil)
|
|
Expect(sc.Name).To(Equal("test-storage-class-2"))
|
|
})
|
|
|
|
It("Should return nil if there's not default storage class", func() {
|
|
client := CreateClient(
|
|
CreateStorageClass("test-storage-class-1", nil),
|
|
CreateStorageClass("test-storage-class-2", nil),
|
|
)
|
|
sc, _ := GetStorageClassByNameWithK8sFallback(context.Background(), client, nil)
|
|
Expect(sc).To(BeNil())
|
|
})
|
|
|
|
It("Should return default virt class even if there's not default k8s storage class", func() {
|
|
client := CreateClient(
|
|
CreateStorageClass("test-storage-class-1", nil),
|
|
CreateStorageClass("test-storage-class-2", map[string]string{
|
|
AnnDefaultVirtStorageClass: "true",
|
|
}),
|
|
)
|
|
sc, _ := GetStorageClassByNameWithVirtFallback(context.Background(), client, nil, cdiv1.DataVolumeKubeVirt)
|
|
Expect(sc.Name).To(Equal("test-storage-class-2"))
|
|
})
|
|
|
|
DescribeTable("Should return newer default", func(annotation string) {
|
|
olderSc := CreateStorageClass("test-storage-class-new", map[string]string{
|
|
annotation: "true",
|
|
})
|
|
olderSc.SetCreationTimestamp(metav1.NewTime(time.Now().Add(-1 * time.Second)))
|
|
newerSc := CreateStorageClass("test-storage-class-old", map[string]string{
|
|
annotation: "true",
|
|
})
|
|
newerSc.SetCreationTimestamp(metav1.NewTime(time.Now()))
|
|
client := CreateClient(newerSc, olderSc)
|
|
sc, _ := GetStorageClassByNameWithVirtFallback(context.Background(), client, nil, cdiv1.DataVolumeKubeVirt)
|
|
Expect(sc.Name).To(Equal(newerSc.Name))
|
|
},
|
|
Entry("virt storage class", AnnDefaultVirtStorageClass),
|
|
Entry("k8s storage class", AnnDefaultStorageClass),
|
|
)
|
|
|
|
DescribeTable("Should fall back to lexicographic order when same timestamp", func(annotation string) {
|
|
firstSc := CreateStorageClass("test-storage-class-1", map[string]string{
|
|
annotation: "true",
|
|
})
|
|
firstSc.SetCreationTimestamp(metav1.NewTime(time.Now()))
|
|
secondSc := CreateStorageClass("test-storage-class-2", map[string]string{
|
|
annotation: "true",
|
|
})
|
|
secondSc.SetCreationTimestamp(metav1.NewTime(time.Now()))
|
|
client := CreateClient(firstSc, secondSc)
|
|
sc, _ := GetStorageClassByNameWithVirtFallback(context.Background(), client, nil, cdiv1.DataVolumeKubeVirt)
|
|
Expect(sc.Name).To(Equal(firstSc.Name))
|
|
},
|
|
Entry("virt storage class", AnnDefaultVirtStorageClass),
|
|
Entry("k8s storage class", AnnDefaultStorageClass),
|
|
)
|
|
})
|
|
|
|
var _ = Describe("Rebind", func() {
|
|
It("Should return error if PV doesn't exist", func() {
|
|
client := CreateClient()
|
|
pvc := &v1.PersistentVolumeClaim{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPVC",
|
|
Namespace: "namespace",
|
|
},
|
|
Spec: v1.PersistentVolumeClaimSpec{
|
|
VolumeName: "testPV",
|
|
},
|
|
}
|
|
err := Rebind(context.Background(), client, pvc, pvc)
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(errors.IsNotFound(err)).To(BeTrue())
|
|
})
|
|
|
|
It("Should return error if bound to unexpected claim", func() {
|
|
pvc := &v1.PersistentVolumeClaim{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPVC",
|
|
Namespace: "namespace",
|
|
},
|
|
Spec: v1.PersistentVolumeClaimSpec{
|
|
VolumeName: "testPV",
|
|
},
|
|
}
|
|
pv := &v1.PersistentVolume{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPV",
|
|
},
|
|
Spec: v1.PersistentVolumeSpec{
|
|
ClaimRef: &v1.ObjectReference{
|
|
Name: "anotherPVC",
|
|
Namespace: "namespace",
|
|
UID: "uid",
|
|
},
|
|
},
|
|
}
|
|
client := CreateClient(pv)
|
|
err := Rebind(context.Background(), client, pvc, pvc)
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(err.Error()).To(Equal("PV testPV bound to unexpected claim anotherPVC"))
|
|
})
|
|
It("Should return nil if bound to target claim", func() {
|
|
pvc := &v1.PersistentVolumeClaim{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPVC",
|
|
Namespace: "namespace",
|
|
},
|
|
Spec: v1.PersistentVolumeClaimSpec{
|
|
VolumeName: "testPV",
|
|
},
|
|
}
|
|
targetPVC := pvc.DeepCopy()
|
|
targetPVC.Name = "targetPVC"
|
|
targetPVC.UID = "uid"
|
|
pv := &v1.PersistentVolume{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPV",
|
|
},
|
|
Spec: v1.PersistentVolumeSpec{
|
|
ClaimRef: &v1.ObjectReference{
|
|
Name: "targetPVC",
|
|
Namespace: "namespace",
|
|
UID: "uid",
|
|
},
|
|
},
|
|
}
|
|
client := CreateClient(pv)
|
|
err := Rebind(context.Background(), client, pvc, targetPVC)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
})
|
|
It("Should rebind pv to target claim", func() {
|
|
pvc := &v1.PersistentVolumeClaim{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPVC",
|
|
Namespace: "namespace",
|
|
},
|
|
Spec: v1.PersistentVolumeClaimSpec{
|
|
VolumeName: "testPV",
|
|
},
|
|
}
|
|
targetPVC := pvc.DeepCopy()
|
|
targetPVC.Name = "targetPVC"
|
|
pvc.UID = "uid"
|
|
pv := &v1.PersistentVolume{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testPV",
|
|
},
|
|
Spec: v1.PersistentVolumeSpec{
|
|
ClaimRef: &v1.ObjectReference{
|
|
Name: "testPVC",
|
|
Namespace: "namespace",
|
|
UID: "uid",
|
|
},
|
|
},
|
|
}
|
|
AddAnnotation(pv, "someAnno", "somevalue")
|
|
client := CreateClient(pv)
|
|
err := Rebind(context.Background(), client, pvc, targetPVC)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
updatedPV := &v1.PersistentVolume{}
|
|
key := types.NamespacedName{Name: pv.Name, Namespace: pv.Namespace}
|
|
err = client.Get(context.TODO(), key, updatedPV)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(updatedPV.Spec.ClaimRef.Name).To(Equal(targetPVC.Name))
|
|
//make sure annotations of pv from before rebind dont get deleted
|
|
Expect(pv.Annotations["someAnno"]).To(Equal("somevalue"))
|
|
})
|
|
})
|
|
|
|
func createPvcNoSize(name, ns string, annotations, labels map[string]string) *v1.PersistentVolumeClaim {
|
|
return &v1.PersistentVolumeClaim{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
Namespace: ns,
|
|
Annotations: annotations,
|
|
Labels: labels,
|
|
},
|
|
}
|
|
}
|