Skip to content

Commit 6734479

Browse files
committed
test/e2e: Add test for Istio manual deployment
This commit resolves NE-1994. https://issues.redhat.com/browse/NE-1994 * test/e2e/gateway_api_test.go (TestGatewayAPI): Run the new test, testGatewayAPIManualDeployment. Update a log message. (testGatewayAPIManualDeployment): New test. Verify that Istio is configured not to allow manual deployment.
1 parent 288f96c commit 6734479

File tree

1 file changed

+106
-1
lines changed

1 file changed

+106
-1
lines changed

test/e2e/gateway_api_test.go

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"strings"
1010
"testing"
11+
"time"
1112

1213
"github.com/openshift/api/features"
1314
operatorclient "github.com/openshift/cluster-ingress-operator/pkg/operator/client"
@@ -18,8 +19,10 @@ import (
1819
"k8s.io/apimachinery/pkg/api/errors"
1920
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2021
"k8s.io/apimachinery/pkg/types"
22+
"k8s.io/apimachinery/pkg/util/wait"
2123
"k8s.io/apiserver/pkg/storage/names"
2224
"k8s.io/client-go/rest"
25+
"k8s.io/utils/ptr"
2326

2427
"sigs.k8s.io/controller-runtime/pkg/client"
2528
"sigs.k8s.io/controller-runtime/pkg/client/config"
@@ -96,9 +99,10 @@ func TestGatewayAPI(t *testing.T) {
9699
t.Run("testGatewayAPIResources", testGatewayAPIResources)
97100
if gatewayAPIControllerEnabled {
98101
t.Run("testGatewayAPIObjects", testGatewayAPIObjects)
102+
t.Run("testGatewayAPIManualDeployment", testGatewayAPIManualDeployment)
99103
t.Run("testGatewayAPIIstioInstallation", testGatewayAPIIstioInstallation)
100104
} else {
101-
t.Log("Gateway API Controller not enabled, skipping testGatewayAPIObjects and testGatewayAPIIstioInstallation")
105+
t.Log("Gateway API Controller not enabled, skipping controller tests")
102106
}
103107
t.Run("testGatewayAPIResourcesProtection", testGatewayAPIResourcesProtection)
104108
}
@@ -191,6 +195,107 @@ func testGatewayAPIObjects(t *testing.T) {
191195
}
192196
}
193197

198+
// testGatewayAPIManualDeployment verifies that Istio's manual deployment is not
199+
// enabled. When manual deployment is enabled, then Istio allows a gateway to
200+
// use another gateway's service by specifying that gateway's service in
201+
// spec.addresses. This results in behavior similar to gateway listener
202+
// merging, which we do not want to allow at this time. Instead, we expect
203+
// Istio to provision a service for this specific gateway, even if it specifies
204+
// spec.addresses.
205+
func testGatewayAPIManualDeployment(t *testing.T) {
206+
gatewayClass, err := createGatewayClass("openshift-default", "openshift.io/gateway-controller/v1")
207+
if err != nil {
208+
t.Fatalf("Failed to create gatewayclass: %v", err)
209+
}
210+
211+
gatewayName := types.NamespacedName{
212+
Name: "manual-deployment",
213+
Namespace: "openshift-ingress",
214+
}
215+
gateway := gatewayapiv1.Gateway{
216+
ObjectMeta: metav1.ObjectMeta{
217+
Name: gatewayName.Name,
218+
Namespace: gatewayName.Namespace,
219+
},
220+
Spec: gatewayapiv1.GatewaySpec{
221+
GatewayClassName: gatewayapiv1.ObjectName(gatewayClass.Name),
222+
Addresses: []gatewayapiv1.GatewayAddress{{
223+
Type: ptr.To(gatewayapiv1.HostnameAddressType),
224+
Value: "lb.example.com",
225+
}},
226+
Listeners: []gatewayapiv1.Listener{{
227+
Name: "http",
228+
Hostname: ptr.To(gatewayapiv1.Hostname(fmt.Sprintf("*.manual-deployment.%s", dnsConfig.Spec.BaseDomain))),
229+
Port: 80,
230+
Protocol: "HTTP",
231+
}},
232+
},
233+
}
234+
t.Logf("Creating gateway %q...", gatewayName)
235+
if err := kclient.Create(context.Background(), &gateway); err != nil {
236+
t.Fatalf("Failed to create gateway %v: %v", gatewayName, err)
237+
}
238+
t.Cleanup(func() {
239+
if err := kclient.Delete(context.Background(), &gateway); err != nil {
240+
if !errors.IsNotFound(err) {
241+
t.Errorf("Failed to delete gateway %v: %v", gatewayName, err)
242+
}
243+
}
244+
})
245+
246+
interval, timeout := 5*time.Second, 1*time.Minute
247+
t.Logf("Polling for up to %v to verify that the gateway is accepted...", timeout)
248+
if err := wait.PollUntilContextTimeout(context.Background(), interval, timeout, false, func(context context.Context) (bool, error) {
249+
if err := kclient.Get(context, gatewayName, &gateway); err != nil {
250+
t.Logf("Failed to get gateway %v: %v; retrying...", gatewayName, err)
251+
252+
return false, nil
253+
}
254+
255+
for _, condition := range gateway.Status.Conditions {
256+
if condition.Type == string(gatewayapiv1.GatewayConditionAccepted) {
257+
t.Logf("Found %q status condition: %+v", gatewayapiv1.GatewayConditionAccepted, condition)
258+
259+
if condition.Status == metav1.ConditionTrue {
260+
return true, nil
261+
}
262+
}
263+
}
264+
265+
t.Logf("Observed that gateway %v is not yet accepted; retrying...", gatewayName)
266+
267+
return false, nil
268+
}); err != nil {
269+
t.Errorf("Failed to observe the expected condition for gateway %v: %v", gatewayName, err)
270+
}
271+
272+
serviceName := types.NamespacedName{
273+
Name: fmt.Sprintf("%s-%s", gateway.Name, gatewayClass.Name),
274+
Namespace: gateway.Namespace,
275+
}
276+
var service corev1.Service
277+
t.Logf("Polling for up to %v to verify that service %q is created...", timeout, serviceName)
278+
if err := wait.PollUntilContextTimeout(context.Background(), interval, timeout, false, func(context context.Context) (bool, error) {
279+
if err := kclient.Get(context, serviceName, &service); err != nil {
280+
t.Logf("Failed to get service %s: %v; retrying...", serviceName, err)
281+
282+
return false, nil
283+
}
284+
285+
// Just verify that the service is created. No need to verify
286+
// that a load balancer is provisioned. Indeed, provisioning
287+
// will likely fail because Istio copies the address hostname to
288+
// the service spec.loadBalancerIP field, which at least some
289+
// cloud provider implementations reject.
290+
291+
t.Logf("Found service %q", serviceName)
292+
293+
return true, nil
294+
}); err != nil {
295+
t.Errorf("Failed to observe the expected condition for service %v: %v", serviceName, err)
296+
}
297+
}
298+
194299
// testGatewayAPIResourcesProtection verifies that the ingress operator's Validating Admission Policy
195300
// denies admission requests attempting to modify Gateway API CRDs on behalf of a user
196301
// who is not the ingress operator's service account.

0 commit comments

Comments
 (0)