Skip to content

Commit

Permalink
add volume attachment trackability
Browse files Browse the repository at this point in the history
  • Loading branch information
britaniar committed Feb 4, 2025
1 parent 51ceeb3 commit b048b86
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
19 changes: 19 additions & 0 deletions pkg/controllers/workapplier/availability_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
appv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
storagev1 "k8s.io/api/storage/v1"
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -83,6 +84,8 @@ func trackInMemberClusterObjAvailabilityByGVR(
return trackCRDAvailability(inMemberClusterObj)
case utils.PodDisruptionBudgetGVR:
return trackPDBAvailability(inMemberClusterObj)
case utils.VolumeAttachmentGVR:
return trackVolumeAttachmentAvailability(inMemberClusterObj)
default:
if isDataResource(*gvr) {
klog.V(2).InfoS("The object from the member cluster is a data object, consider it to be immediately available",
Expand Down Expand Up @@ -247,6 +250,22 @@ func trackPDBAvailability(curObj *unstructured.Unstructured) (ManifestProcessing
return ManifestProcessingAvailabilityResultTypeNotYetAvailable, nil
}

// trackVolumeAttachmentAvailability tracks the availability of a volume attachment in the member cluster
func trackVolumeAttachmentAvailability(curObj *unstructured.Unstructured) (ManifestProcessingAvailabilityResultType, error) {
var volumeAttachment storagev1.VolumeAttachment
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(curObj.Object, &volumeAttachment); err != nil {
return ManifestProcessingAvailabilityResultTypeFailed, controller.NewUnexpectedBehaviorError(err)
}

if volumeAttachment.Status.Attached && volumeAttachment.Status.DetachError == nil {
klog.V(2).InfoS("VolumeAttachment is available", "volumeAttachment", klog.KObj(curObj))
return ManifestProcessingAvailabilityResultTypeAvailable, nil
}

klog.V(2).InfoS("Still need to wait for PodDisruptionBudget to be available", "pdb", klog.KObj(curObj))
return ManifestProcessingAvailabilityResultTypeNotYetAvailable, nil
}

// isDataResource checks if the resource is a data resource; such resources are
// available immediately after creation.
func isDataResource(gvr schema.GroupVersionResource) bool {
Expand Down
77 changes: 77 additions & 0 deletions pkg/controllers/workapplier/availability_tracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ var (
MinAvailable: &minAvailable,
},
}

volumeAttachmentTemplate = &storagev1.VolumeAttachment{
TypeMeta: metav1.TypeMeta{
APIVersion: "storage.k8s.io/v1",
Kind: "VolumeAttachment",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-volume-attachment",
},
Spec: storagev1.VolumeAttachmentSpec{
Attacher: "my-attacher",
NodeName: "my-node",
Source: storagev1.VolumeAttachmentSource{
PersistentVolumeName: ptr.To("my-pv"),
},
},
}
)

// TestTrackDeploymentAvailability tests the trackDeploymentAvailability function.
Expand Down Expand Up @@ -775,6 +792,66 @@ func TestTrackPDBAvailability(t *testing.T) {
}
}

func TestTrackVolumeAttachmentAvailability(t *testing.T) {
availableVolumeAttachment := volumeAttachmentTemplate.DeepCopy()
availableVolumeAttachment.Status = storagev1.VolumeAttachmentStatus{
Attached: true,
}

unavailableVolumeAttachmentAttachError := volumeAttachmentTemplate.DeepCopy()
unavailableVolumeAttachmentAttachError.Status = storagev1.VolumeAttachmentStatus{
Attached: false,
AttachError: &storagev1.VolumeError{
Time: metav1.Now(),
Message: "attacher error",
},
}

unavailableVolumeAttachmentDetachError := volumeAttachmentTemplate.DeepCopy()
unavailableVolumeAttachmentDetachError.Status = storagev1.VolumeAttachmentStatus{
Attached: true,
DetachError: &storagev1.VolumeError{
Time: metav1.Now(),
Message: "detacher error",
},
}

testCases := []struct {
name string
volumeAttachment *storagev1.VolumeAttachment
wantManifestProcessingAvailabilityResultType ManifestProcessingAvailabilityResultType
}{
{
name: "available volume attachment",
volumeAttachment: availableVolumeAttachment,
wantManifestProcessingAvailabilityResultType: ManifestProcessingAvailabilityResultTypeAvailable,
},
{
name: "unavailable attachment (attach error)",
volumeAttachment: unavailableVolumeAttachmentAttachError,
wantManifestProcessingAvailabilityResultType: ManifestProcessingAvailabilityResultTypeNotYetAvailable,
},
{
name: "unavailable attachment (detach error)",
volumeAttachment: unavailableVolumeAttachmentDetachError,
wantManifestProcessingAvailabilityResultType: ManifestProcessingAvailabilityResultTypeNotYetAvailable,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
gotResTyp, err := trackVolumeAttachmentAvailability(toUnstructured(t, tc.volumeAttachment))
if err != nil {
t.Fatalf("trackVolumeAttachmentAvailability() = %v, want no error", err)
}
if gotResTyp != tc.wantManifestProcessingAvailabilityResultType {
t.Errorf("manifestProcessingAvailabilityResultType = %v, want %v", gotResTyp, tc.wantManifestProcessingAvailabilityResultType)
}
})
}

}

// TestTrackInMemberClusterObjAvailabilityByGVR tests the trackInMemberClusterObjAvailabilityByGVR function.
func TestTrackInMemberClusterObjAvailabilityByGVR(t *testing.T) {
availableDeploy := deploy.DeepCopy()
Expand Down
6 changes: 6 additions & 0 deletions pkg/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,12 @@ var (
Resource: "validatingwebhookconfigurations",
}

VolumeAttachmentGVR = schema.GroupVersionResource{
Group: storagev1.SchemeGroupVersion.Group,
Version: storagev1.SchemeGroupVersion.Version,
Resource: "volumeattachments",
}

ClusterResourceOverrideSnapshotKind = schema.GroupVersionKind{
Group: placementv1alpha1.GroupVersion.Group,
Version: placementv1alpha1.GroupVersion.Version,
Expand Down

0 comments on commit b048b86

Please sign in to comment.