Skip to content

Commit

Permalink
change to new files
Browse files Browse the repository at this point in the history
  • Loading branch information
britaniar committed Jan 22, 2025
1 parent 37aa957 commit cede198
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 120 deletions.
19 changes: 0 additions & 19 deletions pkg/controllers/work/apply_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"go.uber.org/atomic"
appv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -42,7 +41,6 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/record"
"k8s.io/component-helpers/apps/poddisruptionbudget"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -455,9 +453,6 @@ func trackResourceAvailability(gvr schema.GroupVersionResource, curObj *unstruct
case utils.CustomResourceDefinitionGVR:
return trackCRDAvailability(curObj)

case utils.PodDisruptionBudgetGVR:
return trackPDBAvailability(curObj)

default:
if isDataResource(gvr) {
klog.V(2).InfoS("Data resources are available immediately", "gvr", gvr, "resource", klog.KObj(curObj))
Expand All @@ -468,20 +463,6 @@ func trackResourceAvailability(gvr schema.GroupVersionResource, curObj *unstruct
}
}

func trackPDBAvailability(curObj *unstructured.Unstructured) (ApplyAction, error) {
var pdb policyv1.PodDisruptionBudget
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(curObj.Object, &pdb); err != nil {
return errorApplyAction, controller.NewUnexpectedBehaviorError(err)
}
// Check if conditions are up-to-date
if poddisruptionbudget.ConditionsAreUpToDate(&pdb) {
klog.V(2).InfoS("PodDisruptionBudget is available", "pdb", klog.KObj(curObj))
return manifestAvailableAction, nil
}
klog.V(2).InfoS("Still need to wait for PodDisruptionBudget to be available", "pdb", klog.KObj(curObj))
return manifestNotAvailableYetAction, nil
}

func trackCRDAvailability(curObj *unstructured.Unstructured) (ApplyAction, error) {
var crd apiextensionsv1.CustomResourceDefinition
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(curObj.Object, &crd); err != nil {
Expand Down
101 changes: 0 additions & 101 deletions pkg/controllers/work/apply_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1420,107 +1420,6 @@ func TestTrackResourceAvailability(t *testing.T) {
expected: manifestNotAvailableYetAction,
err: nil,
},
"Test PodDisruptionBudget available (sufficient pods)": {
gvr: utils.PodDisruptionBudgetGVR,
obj: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "policy/v1",
"kind": "PodDisruptionBudget",
"metadata": map[string]interface{}{
"name": "test-pdb",
"namespace": "default",
"generation": 2,
},
"spec": map[string]interface{}{
"minAvailable": 1,
},
"status": map[string]interface{}{
"currentHealthy": 2,
"desiredHealthy": 1,
"observedGeneration": 2,
"disruptionsAllowed": 1,
"expectedPods": 1,
"conditions": []interface{}{
map[string]interface{}{
"type": "DisruptionAllowed",
"status": "True",
"reason": "SufficientPods",
"observedGeneration": 2,
},
},
},
},
},
expected: manifestAvailableAction,
err: nil,
},
"Test PodDisruptionBudget unavailable (condition not up-to-date)": {
gvr: utils.PodDisruptionBudgetGVR,
obj: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "policy/v1",
"kind": "PodDisruptionBudget",
"metadata": map[string]interface{}{
"name": "test-pdb",
"namespace": "default",
"generation": 2,
},
"spec": map[string]interface{}{
"minAvailable": 1,
},
"status": map[string]interface{}{
"currentHealthy": 2,
"desiredHealthy": 1,
"observedGeneration": 1,
"disruptionsAllowed": 1,
"expectedPods": 1,
"conditions": []interface{}{
map[string]interface{}{
"type": "DisruptionAllowed",
"status": "True",
"reason": "SufficientPods",
},
},
},
},
},
expected: manifestNotAvailableYetAction,
err: nil,
},
"Test PodDisruptionBudget available (insufficient pods)": {
gvr: utils.PodDisruptionBudgetGVR,
obj: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "policy/v1",
"kind": "PodDisruptionBudget",
"metadata": map[string]interface{}{
"name": "test-pdb",
"namespace": "default",
"generation": 2,
},
"spec": map[string]interface{}{
"minAvailable": 1,
},
"status": map[string]interface{}{
"currentHealthy": 2,
"desiredHealthy": 1,
"observedGeneration": 2,
"disruptionsAllowed": 0,
"expectedPods": 1,
"conditions": []interface{}{
map[string]interface{}{
"type": "DisruptionAllowed",
"status": "False",
"reason": "InsufficientPods",
"observedGeneration": 2,
},
},
},
},
},
expected: manifestAvailableAction,
err: nil,
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
Expand Down
18 changes: 18 additions & 0 deletions pkg/controllers/workapplier/availability_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import (

appv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/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"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/component-helpers/apps/poddisruptionbudget"
"k8s.io/klog/v2"

"go.goms.io/fleet/pkg/utils"
Expand Down Expand Up @@ -79,6 +81,8 @@ func trackInMemberClusterObjAvailabilityByGVR(
return trackServiceAvailability(inMemberClusterObj)
case utils.CustomResourceDefinitionGVR:
return trackCRDAvailability(inMemberClusterObj)
case utils.PodDisruptionBudgetGVR:
return trackPDBAvailability(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 @@ -218,6 +222,20 @@ func trackCRDAvailability(inMemberClusterObj *unstructured.Unstructured) (Manife
return ManifestProcessingAvailabilityResultTypeNotYetAvailable, nil
}

func trackPDBAvailability(curObj *unstructured.Unstructured) (ManifestProcessingAvailabilityResultType, error) {
var pdb policyv1.PodDisruptionBudget
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(curObj.Object, &pdb); err != nil {
return ManifestProcessingAvailabilityResultTypeFailed, controller.NewUnexpectedBehaviorError(err)
}
// Check if conditions are up-to-date
if poddisruptionbudget.ConditionsAreUpToDate(&pdb) {
klog.V(2).InfoS("PodDisruptionBudget is available", "pdb", 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
105 changes: 105 additions & 0 deletions pkg/controllers/workapplier/availability_tracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import (
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"

Expand Down Expand Up @@ -136,6 +138,22 @@ var (
},
},
}
minAvailable = intstr.FromInt32(1)

pdbTemplate = &policyv1.PodDisruptionBudget{
TypeMeta: metav1.TypeMeta{
APIVersion: "policy/v1",
Kind: "PodDisruptionBudget",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pdb",
Namespace: nsName,
Generation: 2,
},
Spec: policyv1.PodDisruptionBudgetSpec{
MinAvailable: &minAvailable,
},
}
)

// TestTrackDeploymentAvailability tests the trackDeploymentAvailability function.
Expand Down Expand Up @@ -667,6 +685,93 @@ func TestTrackCRDAvailability(t *testing.T) {
}
}

// TestTrackPDBAvailability tests the trackPDBAvailability function.
func TestTrackPDBAvailability(t *testing.T) {
availablePDB := pdbTemplate.DeepCopy()
availablePDB.Status = policyv1.PodDisruptionBudgetStatus{
DisruptionsAllowed: 1,
CurrentHealthy: 2,
ObservedGeneration: 2,
DesiredHealthy: 2,
ExpectedPods: 1,
Conditions: []metav1.Condition{
{
Type: policyv1.DisruptionAllowedCondition,
Status: metav1.ConditionTrue,
Reason: policyv1.SufficientPodsReason,
ObservedGeneration: 2,
},
},
}
unavailablePDBInsufficientPods := pdbTemplate.DeepCopy()
unavailablePDBInsufficientPods.Status = policyv1.PodDisruptionBudgetStatus{
DisruptionsAllowed: 0,
CurrentHealthy: 1,
ObservedGeneration: 2,
DesiredHealthy: 2,
ExpectedPods: 1,
Conditions: []metav1.Condition{
{
Type: policyv1.DisruptionAllowedCondition,
Status: metav1.ConditionTrue,
Reason: policyv1.SufficientPodsReason,
ObservedGeneration: 2,
},
},
}

unavailablePDBStaleCondition := pdbTemplate.DeepCopy()
unavailablePDBStaleCondition.Status = policyv1.PodDisruptionBudgetStatus{
DisruptionsAllowed: 1,
CurrentHealthy: 2,
ObservedGeneration: 1,
DesiredHealthy: 2,
ExpectedPods: 1,
Conditions: []metav1.Condition{
{
Type: policyv1.DisruptionAllowedCondition,
Status: metav1.ConditionTrue,
Reason: policyv1.SufficientPodsReason,
ObservedGeneration: 1,
},
},
}

testCases := []struct {
name string
pdb *policyv1.PodDisruptionBudget
wantManifestProcessingAvailabilityResultType ManifestProcessingAvailabilityResultType
}{
{
name: "available PDB",
pdb: availablePDB,
wantManifestProcessingAvailabilityResultType: ManifestProcessingAvailabilityResultTypeAvailable,
},
{
name: "unavailable PDB (insufficient pods)",
pdb: unavailablePDBInsufficientPods,
wantManifestProcessingAvailabilityResultType: ManifestProcessingAvailabilityResultTypeNotYetAvailable,
},
{
name: "unavailable PDB (stale condition)",
pdb: unavailablePDBStaleCondition,
wantManifestProcessingAvailabilityResultType: ManifestProcessingAvailabilityResultTypeNotYetAvailable,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
gotResTyp, err := trackPDBAvailability(toUnstructured(t, tc.pdb))
if err != nil {
t.Fatalf("trackPDBAvailability() = %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

0 comments on commit cede198

Please sign in to comment.