Skip to content

Commit

Permalink
Sync PVC's Status.Phase
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanchen8911 committed Aug 16, 2023
1 parent ba5a6e8 commit 9ea7979
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 0 deletions.
1 change: 1 addition & 0 deletions virtualcluster/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
k8s.io/client-go v0.21.9
k8s.io/code-generator v0.21.9
k8s.io/component-base v0.21.9
k8s.io/klog v1.0.0 // indirect
k8s.io/klog/v2 v2.9.0
k8s.io/utils v0.0.0-20210527160623-6fdb442a123b
sigs.k8s.io/cluster-api v0.4.0-beta.0
Expand Down
2 changes: 2 additions & 0 deletions virtualcluster/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,8 @@ k8s.io/component-helpers v0.21.9/go.mod h1:iD1KhUeryajzGXCd8VmwxAGH+m09LOUGx0rQI
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
Expand Down
12 changes: 12 additions & 0 deletions virtualcluster/pkg/syncer/conversion/equality.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog"
"k8s.io/utils/pointer"

"sigs.k8s.io/cluster-api-provider-nested/virtualcluster/pkg/apis/tenancy/v1alpha1"
Expand Down Expand Up @@ -741,6 +742,17 @@ func (e vcEquality) CheckUWPVCStatusEquality(pObj, vObj *v1.PersistentVolumeClai
}
updated.Status.Capacity["storage"] = pObj.Status.Capacity["storage"]
}

// Check if a tenant cluster's PVC(vPVC) is bound but a super cluster's PVC (pPVC) is not bound.
// In this case, update the vPVC's Status.Phase.
if vObj.Status.Phase == v1.ClaimBound && pObj.Status.Phase != v1.ClaimBound {
if updated == nil {
updated = vObj.DeepCopy()
}
klog.Warningf("Virtual cluster's PVC %s in %s is bound while the super cluster's PVC %s is not bound", vObj.Name, vObj.ClusterName, pObj.Name)
updated.Status.Phase = pObj.Status.Phase
}

return updated
}

Expand Down
134 changes: 134 additions & 0 deletions virtualcluster/pkg/syncer/conversion/equality_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"

"sigs.k8s.io/cluster-api-provider-nested/virtualcluster/pkg/apis/tenancy/v1alpha1"
Expand Down Expand Up @@ -979,3 +980,136 @@ func TestCheckDWPodConditionEquality(t *testing.T) {
})
}
}

func TestCheckUWPVCStatusEquality(t *testing.T) {
for _, tt := range []struct {
name string
pObj *v1.PersistentVolumeClaim
vObj *v1.PersistentVolumeClaim
updatedObj *v1.PersistentVolumeClaim
}{
{
name: "pPVC is pending and vPVC is pending",
pObj: &v1.PersistentVolumeClaim{
Status: v1.PersistentVolumeClaimStatus{
Phase: "Pending",
},
},
vObj: &v1.PersistentVolumeClaim{
Status: v1.PersistentVolumeClaimStatus{
Phase: "Pending",
},
},
updatedObj: nil,
},
{
name: "pPVC is bound and vPVC is bound",
pObj: &v1.PersistentVolumeClaim{
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
},
},
vObj: &v1.PersistentVolumeClaim{
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
},
},
updatedObj: nil,
},
{
name: "pPVC is lost and vPVC is lost",
pObj: &v1.PersistentVolumeClaim{
Status: v1.PersistentVolumeClaimStatus{
Phase: "Lost",
},
},
vObj: &v1.PersistentVolumeClaim{
Status: v1.PersistentVolumeClaimStatus{
Phase: "Lost",
},
},
updatedObj: nil,
},
{
name: "pPVC is lost and vPVC is bound",
pObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: "Lost",
},
},
vObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "vPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
},
},
updatedObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "vPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: "Lost",
},
},
},
{
name: "pPVC is pending and vPVC is bound",
pObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: "Pending",
},
},
vObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "vPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
},
},
updatedObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "vPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: "Pending",
},
},
},
{
name: "pPVC is bound and vPVC is pending",
pObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
},
},
vObj: &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "vPVC",
},
Status: v1.PersistentVolumeClaimStatus{
Phase: "Pending",
},
},
updatedObj: nil,
},
} {
t.Run(tt.name, func(tc *testing.T) {
obj := Equality(nil, nil).CheckUWPVCStatusEquality(tt.pObj, tt.vObj)
if obj != nil && obj.Status.Phase != tt.updatedObj.Status.Phase {
tc.Errorf("expected vPVC's Status.Phase: %v, got: %v", tt.updatedObj.Status.Phase, obj.Status.Phase)
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"testing"

corev1 "k8s.io/api/core/v1"

Check failure on line 22 in virtualcluster/pkg/syncer/resources/persistentvolumeclaim/checker_test.go

View workflow job for this annotation

GitHub Actions / lint (virtualcluster)

ST1019: package "k8s.io/api/core/v1" is being imported more than once (stylecheck)

Check failure on line 22 in virtualcluster/pkg/syncer/resources/persistentvolumeclaim/checker_test.go

View workflow job for this annotation

GitHub Actions / lint (virtualcluster)

ST1019: package "k8s.io/api/core/v1" is being imported more than once (stylecheck)
v1 "k8s.io/api/core/v1"

Check failure on line 23 in virtualcluster/pkg/syncer/resources/persistentvolumeclaim/checker_test.go

View workflow job for this annotation

GitHub Actions / lint (virtualcluster)

import "k8s.io/api/core/v1" imported as "v1" but must be "corev1" according to config (importas)

Check failure on line 23 in virtualcluster/pkg/syncer/resources/persistentvolumeclaim/checker_test.go

View workflow job for this annotation

GitHub Actions / lint (virtualcluster)

import "k8s.io/api/core/v1" imported as "v1" but must be "corev1" according to config (importas)
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -32,6 +33,23 @@ import (
util "sigs.k8s.io/cluster-api-provider-nested/virtualcluster/pkg/syncer/util/test"
)

var (
statusPending = &corev1.PersistentVolumeClaimStatus{
Phase: v1.ClaimPending,
}
statusBound = &corev1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
}
statusLost = &corev1.PersistentVolumeClaimStatus{
Phase: v1.ClaimLost,
}
)

func applyStatusToPVC(pvc *corev1.PersistentVolumeClaim, pvs *corev1.PersistentVolumeClaimStatus) *corev1.PersistentVolumeClaim {
pvc.Status.Phase = (*pvs).Phase

Check failure on line 49 in virtualcluster/pkg/syncer/resources/persistentvolumeclaim/checker_test.go

View workflow job for this annotation

GitHub Actions / lint (virtualcluster)

underef: could simplify (*pvs).Phase to pvs.Phase (gocritic)

Check failure on line 49 in virtualcluster/pkg/syncer/resources/persistentvolumeclaim/checker_test.go

View workflow job for this annotation

GitHub Actions / lint (virtualcluster)

underef: could simplify (*pvs).Phase to pvs.Phase (gocritic)
return pvc
}

func TestPVCPatrol(t *testing.T) {
testTenant := &v1alpha1.VirtualCluster{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -130,6 +148,37 @@ func TestPVCPatrol(t *testing.T) {
},
WaitDWS: true,
},
"pPVC is lost, vPVC is bound": {
ExistingObjectInSuper: []runtime.Object{
applyStatusToPVC(superPVC("pvc-3", superDefaultNSName, "12345", defaultClusterKey), statusLost),
},
ExistingObjectInTenant: []runtime.Object{
applyStatusToPVC(tenantPVC("pvc-3", "default", "12345"), statusBound),
},
// TODO: Set ExpectedUpdatedVObject with Status.Phase="Lost"
ExpectedNoOperation: false,
WaitUWS: true,
},
"pPVC is bound, vPVC is pending": {
ExistingObjectInSuper: []runtime.Object{
applyStatusToPVC(superPVC("pvc-3", superDefaultNSName, "12345", defaultClusterKey), statusBound),
},
ExistingObjectInTenant: []runtime.Object{
applyStatusToPVC(tenantPVC("pvc-3", "default", "12345"), statusPending),
},
ExpectedUpdatedVObject: []runtime.Object{},
ExpectedNoOperation: true,
},
"pPVC is pending, vPVC is pending": {
ExistingObjectInSuper: []runtime.Object{
applyStatusToPVC(superPVC("pvc-3", superDefaultNSName, "12345", defaultClusterKey), statusPending),
},
ExistingObjectInTenant: []runtime.Object{
applyStatusToPVC(tenantPVC("pvc-3", "default", "12345"), statusPending),
},
ExpectedUpdatedVObject: []runtime.Object{},
ExpectedNoOperation: true,
},
}

for k, tc := range testcases {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,41 @@ func TestUWPVCUpdate(t *testing.T) {
"default/pvc-1",
},
},
"pPVC is lost, vPVC is bound": {
ExistingObjectInSuper: []runtime.Object{
applyStatusToPVC(superPVC("pvc-1", superDefaultNSName, "12345", defaultClusterKey), statusLost),
},
ExistingObjectInTenant: []runtime.Object{
applyStatusToPVC(tenantPVC("pvc-1", "default", "12345"), statusBound),
},
EnqueuedKey: superDefaultNSName + "/pvc-1",
ExpectedError: "",
ExpectedUpdatedObject: []string{
"default/pvc-1",
},
},
"pPVC is bound, vPVC is pending": {
ExistingObjectInSuper: []runtime.Object{
applyStatusToPVC(superPVC("pvc-1", superDefaultNSName, "12345", defaultClusterKey), statusBound),
},
ExistingObjectInTenant: []runtime.Object{
applyStatusToPVC(tenantPVC("pvc-1", "default", "12345"), statusPending),
},
EnqueuedKey: superDefaultNSName + "/pvc-1",
ExpectedError: "",
ExpectedUpdatedObject: []string{},
},
"pPVC is pending, vPVC is pending": {
ExistingObjectInSuper: []runtime.Object{
applyStatusToPVC(superPVC("pvc-1", superDefaultNSName, "12345", defaultClusterKey), statusPending),
},
ExistingObjectInTenant: []runtime.Object{
applyStatusToPVC(tenantPVC("pvc-1", "default", "12345"), statusPending),
},
EnqueuedKey: superDefaultNSName + "/pvc-1",
ExpectedError: "",
ExpectedUpdatedObject: []string{},
},
}

for k, tc := range testcases {
Expand Down

0 comments on commit 9ea7979

Please sign in to comment.