Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions pkg/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,27 @@ func IsStatusAvailable(client runtimeclient.Client, name string) bool {
return true
}

func IsStatusDegraded(client runtimeclient.Client, name string) (bool, error) {
key := types.NamespacedName{
Namespace: MachineAPINamespace,
Name: name,
}
clusterOperator := &configv1.ClusterOperator{}
if err := client.Get(context.TODO(), key, clusterOperator); err != nil {
return false, fmt.Errorf("error querying api for OperatorStatus object: %v, retrying...", err)
}

isAvailable := cov1helpers.IsStatusConditionTrue(clusterOperator.Status.Conditions, configv1.OperatorAvailable)
isDegraded := cov1helpers.IsStatusConditionTrue(clusterOperator.Status.Conditions, configv1.OperatorDegraded)
isProgressing := cov1helpers.IsStatusConditionTrue(clusterOperator.Status.Conditions, configv1.OperatorProgressing)

klog.Infof("Condition: %q is %v, expected true", configv1.OperatorAvailable, isAvailable)
klog.Infof("Condition: %q is %v, expected true", configv1.OperatorDegraded, isDegraded)
klog.Infof("Condition: %q is %v, expected false", configv1.OperatorProgressing, isProgressing)

return isAvailable && isDegraded && !isProgressing, nil
}

func WaitForValidatingWebhook(client runtimeclient.Client, name string) bool {
key := types.NamespacedName{Name: name}
webhook := &admissionregistrationv1beta1.ValidatingWebhookConfiguration{}
Expand Down
45 changes: 45 additions & 0 deletions pkg/operators/machine-api-operator.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package operators

import (
"context"
"fmt"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/openshift/cluster-api-actuator-pkg/pkg/framework"
v1 "k8s.io/api/core/v1"
"k8s.io/klog"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
)

var (
Expand Down Expand Up @@ -75,4 +79,45 @@ var _ = Describe("[Feature:Operators] Machine API cluster operator status should
Expect(err).NotTo(HaveOccurred())
Expect(framework.IsStatusAvailable(client, "machine-api")).To(BeTrue())
})

It("be degraded when a pod owned by the operator is prevented from being available", func() {
c, err := framework.LoadClient()
Expect(err).NotTo(HaveOccurred())

// https://github.com/openshift/machine-api-operator/blob/d234cceb5de18b83aa0609d17db7d835f2d78973/pkg/operator/sync.go#L310-L313
mAPIControllersLabels := map[string]string{
"api": "clusterapi",
"k8s-app": "controller",
}

Eventually(func() (bool, error) {
// get machine API controllers pods
podList := &v1.PodList{}
if err := c.List(context.TODO(), podList, client.MatchingLabels(mAPIControllersLabels)); err != nil {
klog.Errorf("failed to list pods: %v", err)
return false, nil
}
if len(podList.Items) < 1 {
klog.Errorf("list of pods is empty")
return false, nil
}
Comment on lines +100 to +103

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this matter? If the list of pods is empty, status should be degraded right?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it doesn't matter, but do we expect pods not to be running when at this part of the test?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well my thought was we go through this cycle, delete a pod, status isn't degraded yet, so start again, pod has not been recreated yet, could the status be degraded by this point? I am not sure, I would assume they are independent since they're different controllers controlling these actions


// delete machine API controllers pods
for k := range podList.Items {
if err := c.Delete(context.Background(), &podList.Items[k]); err != nil {
klog.Errorf("failed to delete pod: %v", err)
return false, nil
}
}

isStatusDegraded, err := framework.IsStatusDegraded(c, "machine-api")
if err != nil {
return false, nil
}

return isStatusDegraded, nil
}, framework.WaitLong, framework.RetryShort).Should(BeTrue())

Expect(framework.IsStatusAvailable(c, "machine-api")).To(BeTrue())
})
})