@@ -17,6 +17,7 @@ import (
1717
1818 "github.com/stretchr/testify/require"
1919 corev1 "k8s.io/api/core/v1"
20+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2021 "k8s.io/apimachinery/pkg/types"
2122 "k8s.io/apimachinery/pkg/util/wait"
2223 gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
@@ -26,6 +27,7 @@ import (
2627 "sigs.k8s.io/gateway-api/conformance/utils/suite"
2728 "sigs.k8s.io/gateway-api/conformance/utils/tlog"
2829
30+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
2931 "github.com/envoyproxy/gateway/internal/gatewayapi"
3032 "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
3133)
@@ -48,7 +50,7 @@ var OIDCTest = suite.ConformanceTest{
4850 Manifests : []string {"testdata/oidc-keycloak.yaml" , "testdata/oidc-securitypolicy.yaml" },
4951 Test : func (t * testing.T , suite * suite.ConformanceTestSuite ) {
5052 t .Run ("oidc provider represented by a URL" , func (t * testing.T ) {
51- testOIDC (t , suite )
53+ testOIDC (t , suite , "testdata/oidc-securitypolicy.yaml" )
5254 })
5355
5456 t .Run ("http route without oidc authentication" , func (t * testing.T ) {
@@ -92,7 +94,7 @@ var OIDCTest = suite.ConformanceTest{
9294 },
9395}
9496
95- func testOIDC (t * testing.T , suite * suite.ConformanceTestSuite ) {
97+ func testOIDC (t * testing.T , suite * suite.ConformanceTestSuite , securityPolicyManifest string ) {
9698 var (
9799 testURL = "http://www.example.com/myapp"
98100 logoutURL = "http://www.example.com/myapp/logout"
@@ -119,7 +121,7 @@ func testOIDC(t *testing.T, suite *suite.ConformanceTestSuite) {
119121 WaitForPods (t , suite .Client , ns , map [string ]string {"job-name" : "setup-keycloak" }, corev1 .PodSucceeded , podInitialized )
120122
121123 // Initialize the test OIDC client that will keep track of the state of the OIDC login process
122- client , err := NewOIDCTestClient (
124+ oidcClient , err := NewOIDCTestClient (
123125 WithLoggingOptions (t .Log , true ),
124126 // Map the application and keycloak cluster DNS name to the gateway address
125127 WithCustomAddressMappings (map [string ]string {
@@ -135,13 +137,31 @@ func testOIDC(t *testing.T, suite *suite.ConformanceTestSuite) {
135137
136138 // Send a request to the http route with OIDC configured.
137139 // It will be redirected to the keycloak login page
138- res , err := client .Get (testURL , true )
139- require .NoError (t , err , "Failed to get the login page" )
140- require .Equal (t , 200 , res .StatusCode , "Expected 200 OK" )
140+ res , err := oidcClient .Get (testURL , true )
141+ if err != nil {
142+ tlog .Logf (t , "failed to get the login page: %v" , err )
143+ return false , nil
144+ }
145+ if res .StatusCode != http .StatusOK {
146+ tlog .Logf (t , "Failed to get the login page, expected 200 OK, got %d" , res .StatusCode )
147+ return false , nil
148+ }
141149
142150 // Parse the response body to get the URL where the login page would post the user-entered credentials
143- if err := client .ParseLoginForm (res .Body , keyCloakLoginFormID ); err != nil {
151+ if err := oidcClient .ParseLoginForm (res .Body , keyCloakLoginFormID ); err != nil {
144152 tlog .Logf (t , "failed to parse login form: %v" , err )
153+ // recreate the security policy to force repushing the configuration to the envoy proxy to recover from the error.
154+ // This is a workaround for the flaky test: https://github.com/envoyproxy/gateway/issues/3898
155+ // TODO: we should investigate the root cause of the flakiness and remove this workaround
156+ existingSP := & egv1a1.SecurityPolicy {
157+ ObjectMeta : metav1.ObjectMeta {
158+ Namespace : ns ,
159+ Name : sp ,
160+ },
161+ }
162+ require .NoError (t , suite .Client .Delete (context .TODO (), existingSP ))
163+ suite .Applier .MustApplyWithCleanup (t , suite .Client , suite .TimeoutConfig , securityPolicyManifest , false )
164+ SecurityPolicyMustBeAccepted (t , suite .Client , types.NamespacedName {Name : sp , Namespace : ns }, suite .ControllerName , ancestorRef )
145165 return false , nil
146166 }
147167
@@ -153,7 +173,7 @@ func testOIDC(t *testing.T, suite *suite.ConformanceTestSuite) {
153173
154174 // Submit the login form to the IdP.
155175 // This will authenticate and redirect back to the application
156- res , err := client .Login (map [string ]string {"username" : username , "password" : password , "credentialId" : "" })
176+ res , err := oidcClient .Login (map [string ]string {"username" : username , "password" : password , "credentialId" : "" })
157177 require .NoError (t , err , "Failed to login to the IdP" )
158178
159179 // Verify that we get the expected response from the application
@@ -163,14 +183,14 @@ func testOIDC(t *testing.T, suite *suite.ConformanceTestSuite) {
163183 require .Contains (t , string (body ), "infra-backend-v1" , "Expected response from the application" )
164184
165185 // Verify that we can access the application without logging in again
166- res , err = client .Get (testURL , false )
186+ res , err = oidcClient .Get (testURL , false )
167187 require .NoError (t , err )
168188 require .Equal (t , http .StatusOK , res .StatusCode )
169189 require .Contains (t , string (body ), "infra-backend-v1" , "Expected response from the application" )
170190
171191 // Verify that we can logout
172192 // Note: OAuth2 filter just clears its cookies and does not log out from the IdP.
173- res , err = client .Get (logoutURL , false )
193+ res , err = oidcClient .Get (logoutURL , false )
174194 require .NoError (t , err )
175195 require .Equal (t , http .StatusFound , res .StatusCode )
176196
0 commit comments