Skip to content

Commit 879fcc8

Browse files
Merge pull request #7151 from muraee/fix-OCPBUGS-63353
OCPBUGS-63353: Fix ValidAWSIdentityProvider status when KAS is unavailable
2 parents dd940af + 09d1e48 commit 879fcc8

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

control-plane-operator/controllers/healthcheck/aws.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,33 @@ import (
1515
)
1616

1717
func awsHealthCheckIdentityProvider(ctx context.Context, hcp *hyperv1.HostedControlPlane) error {
18+
// Check if KAS is available before attempting to validate AWS identity provider.
19+
// The AWS identity provider validation requires a token to be minted, which requires KAS to be up.
20+
kasAvailable := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.KubeAPIServerAvailable))
21+
if kasAvailable == nil || kasAvailable.Status != metav1.ConditionTrue {
22+
// KAS is not available, cannot validate AWS identity provider
23+
condition := metav1.Condition{
24+
Type: string(hyperv1.ValidAWSIdentityProvider),
25+
ObservedGeneration: hcp.Generation,
26+
Status: metav1.ConditionUnknown,
27+
Message: "Cannot validate AWS identity provider while KubeAPIServer is not available",
28+
Reason: hyperv1.StatusUnknownReason,
29+
}
30+
meta.SetStatusCondition(&hcp.Status.Conditions, condition)
31+
return nil
32+
}
33+
1834
ec2Client, _ := hostedcontrolplane.GetEC2Client()
1935
if ec2Client == nil {
36+
// EC2 client is not available (token minting may have failed)
37+
condition := metav1.Condition{
38+
Type: string(hyperv1.ValidAWSIdentityProvider),
39+
ObservedGeneration: hcp.Generation,
40+
Status: metav1.ConditionUnknown,
41+
Message: "AWS EC2 client is not available",
42+
Reason: hyperv1.StatusUnknownReason,
43+
}
44+
meta.SetStatusCondition(&hcp.Status.Conditions, condition)
2045
return nil
2146
}
2247

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package healthcheck
2+
3+
import (
4+
"testing"
5+
6+
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
7+
8+
"k8s.io/apimachinery/pkg/api/meta"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
)
11+
12+
// TestAWSHealthCheckIdentityProviderConditionLogic tests the condition setting logic
13+
// when KAS is not available. This validates that the function correctly sets the
14+
// ValidAWSIdentityProvider condition to Unknown when it cannot perform validation.
15+
func TestAWSHealthCheckIdentityProviderConditionLogic(t *testing.T) {
16+
testCases := []struct {
17+
name string
18+
kasCondition *metav1.Condition
19+
expectedStatus metav1.ConditionStatus
20+
expectedReason string
21+
expectedMessage string
22+
}{
23+
{
24+
name: "KAS not available - condition missing",
25+
kasCondition: nil,
26+
expectedStatus: metav1.ConditionUnknown,
27+
expectedReason: hyperv1.StatusUnknownReason,
28+
expectedMessage: "Cannot validate AWS identity provider while KubeAPIServer is not available",
29+
},
30+
{
31+
name: "KAS not available - condition False",
32+
kasCondition: &metav1.Condition{
33+
Type: string(hyperv1.KubeAPIServerAvailable),
34+
Status: metav1.ConditionFalse,
35+
},
36+
expectedStatus: metav1.ConditionUnknown,
37+
expectedReason: hyperv1.StatusUnknownReason,
38+
expectedMessage: "Cannot validate AWS identity provider while KubeAPIServer is not available",
39+
},
40+
{
41+
name: "KAS not available - condition Unknown",
42+
kasCondition: &metav1.Condition{
43+
Type: string(hyperv1.KubeAPIServerAvailable),
44+
Status: metav1.ConditionUnknown,
45+
},
46+
expectedStatus: metav1.ConditionUnknown,
47+
expectedReason: hyperv1.StatusUnknownReason,
48+
expectedMessage: "Cannot validate AWS identity provider while KubeAPIServer is not available",
49+
},
50+
{
51+
name: "KAS available",
52+
kasCondition: &metav1.Condition{
53+
Type: string(hyperv1.KubeAPIServerAvailable),
54+
Status: metav1.ConditionTrue,
55+
},
56+
expectedStatus: metav1.ConditionUnknown,
57+
expectedReason: hyperv1.StatusUnknownReason,
58+
expectedMessage: "AWS EC2 client is not available",
59+
},
60+
}
61+
62+
for _, tc := range testCases {
63+
t.Run(tc.name, func(t *testing.T) {
64+
// Create a test HCP
65+
hcp := &hyperv1.HostedControlPlane{
66+
ObjectMeta: metav1.ObjectMeta{
67+
Name: "test-hcp",
68+
Namespace: "test-namespace",
69+
Generation: 1,
70+
},
71+
Status: hyperv1.HostedControlPlaneStatus{
72+
Conditions: []metav1.Condition{},
73+
},
74+
}
75+
76+
// Add KAS condition if specified
77+
if tc.kasCondition != nil {
78+
meta.SetStatusCondition(&hcp.Status.Conditions, *tc.kasCondition)
79+
}
80+
81+
err := awsHealthCheckIdentityProvider(t.Context(), hcp)
82+
if err != nil {
83+
t.Errorf("Expected no error but got: %v", err)
84+
}
85+
86+
// Verify the ValidAWSIdentityProvider condition was set correctly
87+
condition := meta.FindStatusCondition(hcp.Status.Conditions, string(hyperv1.ValidAWSIdentityProvider))
88+
if condition == nil {
89+
t.Fatal("ValidAWSIdentityProvider condition was not set")
90+
return
91+
}
92+
93+
if condition.Status != tc.expectedStatus {
94+
t.Errorf("Expected status %v, got %v", tc.expectedStatus, condition.Status)
95+
}
96+
97+
if condition.Reason != tc.expectedReason {
98+
t.Errorf("Expected reason %v, got %v", tc.expectedReason, condition.Reason)
99+
}
100+
101+
if tc.expectedMessage != "" && condition.Message != tc.expectedMessage {
102+
t.Errorf("Expected message %q, got %q", tc.expectedMessage, condition.Message)
103+
}
104+
105+
if condition.ObservedGeneration != hcp.Generation {
106+
t.Errorf("Expected ObservedGeneration %v, got %v", hcp.Generation, condition.ObservedGeneration)
107+
}
108+
})
109+
}
110+
}

0 commit comments

Comments
 (0)