blob: 99283cacb6618af6cda1b6bbcd1747dc4738ce38 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package gatewayapi
import (
"fmt"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/apache/apisix-ingress-controller/internal/types"
"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
)
var _ = Describe("Test GatewayProxy", Label("apisix.apache.org", "v1alpha1", "gatewayproxy"), func() {
s := scaffold.NewDefaultScaffold()
var defaultGatewayClass = `
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: %s
spec:
controllerName: %s
`
var gatewayWithProxy = `
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: %s
spec:
gatewayClassName: %s
listeners:
- name: http
protocol: HTTP
port: 80
infrastructure:
parametersRef:
group: apisix.apache.org
kind: GatewayProxy
name: %s
`
var gatewayProxyWithEnabledPlugin = `
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
name: %s
spec:
provider:
type: ControlPlane
controlPlane:
endpoints:
- %s
auth:
type: AdminKey
adminKey:
value: "%s"
plugins:
- name: response-rewrite
enabled: true
config:
headers:
X-Proxy-Test: "enabled"
`
var gatewayProxyWithDisabledPlugin = `
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
name: %s
spec:
provider:
type: ControlPlane
controlPlane:
endpoints:
- %s
auth:
type: AdminKey
adminKey:
value: "%s"
plugins:
- name: response-rewrite
enabled: false
config:
headers:
X-Proxy-Test: "disabled"
`
var httpRouteForTest = `
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: test-route
spec:
parentRefs:
- name: %s
hostnames:
- example.com
rules:
- matches:
- path:
type: Exact
value: /get
backendRefs:
- name: httpbin-service-e2e-test
port: 80
`
var (
gatewayClassName string
)
BeforeEach(func() {
By("Create GatewayClass")
gatewayClassName = s.Namespace()
err := s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGatewayClass, gatewayClassName, s.GetControllerName()), "")
Expect(err).NotTo(HaveOccurred(), "creating GatewayClass")
time.Sleep(5 * time.Second)
By("Check GatewayClass condition")
gcYaml, err := s.GetResourceYaml(types.KindGatewayClass, gatewayClassName)
Expect(err).NotTo(HaveOccurred(), "getting GatewayClass yaml")
Expect(gcYaml).To(ContainSubstring(`status: "True"`), "checking GatewayClass condition status")
Expect(gcYaml).To(ContainSubstring("message: the gatewayclass has been accepted by the apisix-ingress-controller"), "checking GatewayClass condition message")
By("Create GatewayProxy with enabled plugin")
err = s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithEnabledPlugin, s.Namespace(), s.Deployer.GetAdminEndpoint(), s.AdminKey()))
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy with enabled plugin")
time.Sleep(5 * time.Second)
By("Create Gateway with GatewayProxy")
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayWithProxy, s.Namespace(), gatewayClassName, s.Namespace()), s.Namespace())
Expect(err).NotTo(HaveOccurred(), "creating Gateway with GatewayProxy")
time.Sleep(5 * time.Second)
By("check Gateway condition")
gwyaml, err := s.GetResourceYaml(types.KindGateway, s.Namespace())
Expect(err).NotTo(HaveOccurred(), "getting Gateway yaml")
Expect(gwyaml).To(ContainSubstring(`status: "True"`), "checking Gateway condition status")
Expect(gwyaml).To(ContainSubstring("message: the gateway has been accepted by the apisix-ingress-controller"), "checking Gateway condition message")
})
Context("Test Gateway with enabled GatewayProxy plugin", func() {
It("Should apply plugin configuration when enabled", func() {
By("Create HTTPRoute for Gateway with GatewayProxy")
s.ResourceApplied(types.KindHTTPRoute, "test-route", fmt.Sprintf(httpRouteForTest, s.Namespace()), 1)
By("Check if the plugin is applied")
s.RequestAssert(&scaffold.RequestAssert{
Method: "GET",
Path: "/get",
Host: "example.com",
Checks: []scaffold.ResponseCheckFunc{
scaffold.WithExpectedStatus(200),
scaffold.WithExpectedHeader("X-Proxy-Test", "enabled"),
},
})
By("Update GatewayProxy with disabled plugin")
err := s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithDisabledPlugin, s.Namespace(), s.Deployer.GetAdminEndpoint(), s.AdminKey()))
Expect(err).NotTo(HaveOccurred(), "updating GatewayProxy with disabled plugin")
By("Create HTTPRoute for Gateway with GatewayProxy")
s.ResourceApplied(types.KindHTTPRoute, "test-route", fmt.Sprintf(httpRouteForTest, s.Namespace()), 1)
By("Check if the plugin is not applied")
s.RequestAssert(&scaffold.RequestAssert{
Method: "GET",
Path: "/get",
Host: "example.com",
Checks: []scaffold.ResponseCheckFunc{
scaffold.WithExpectedStatus(200),
scaffold.WithExpectedHeader("X-Proxy-Test", ""),
},
})
By("should fail to apply GatewayProxy with invalid endpoint")
var gatewayProxyWithInvalidEndpoint = `
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
name: %s
spec:
provider:
type: ControlPlane
controlPlane:
endpoints:
- "http://invalid-endpoint:9180"
- %s
auth:
type: AdminKey
adminKey:
value: "%s"
`
By("Update GatewayProxy with invalid endpoint")
err = s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithInvalidEndpoint, s.Namespace(), s.Deployer.GetAdminEndpoint(), s.AdminKey()))
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy with enabled plugin")
By("Create HTTPRoute")
s.ResourceApplied(types.KindHTTPRoute, "test-route", fmt.Sprintf(httpRouteForTest, s.Namespace()), 1)
s.RequestAssert(&scaffold.RequestAssert{
Method: "GET",
Path: "/get",
Host: "example.com",
Checks: []scaffold.ResponseCheckFunc{
scaffold.WithExpectedStatus(200),
scaffold.WithExpectedHeader("X-Proxy-Test", ""),
},
})
})
})
Context("Test GatewayProxy Provider Validation", func() {
var (
gatewayProxyWithInvalidProviderType = `
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
name: %s
spec:
provider:
type: "InvalidType"
`
gatewayProxyWithMissingControlPlane = `
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
name: %s
spec:
provider:
type: "ControlPlane"
`
gatewayProxyWithValidProvider = `
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
name: %s
spec:
provider:
type: "ControlPlane"
controlPlane:
endpoints:
- "http://localhost:9180"
auth:
type: "AdminKey"
adminKey:
value: "test-key"
`
)
It("Should reject invalid provider type", func() {
By("Create GatewayProxy with invalid provider type")
err := s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithInvalidProviderType, s.Namespace()))
Expect(err).To(HaveOccurred(), "creating GatewayProxy with invalid provider type")
Expect(err.Error()).To(ContainSubstring("Invalid value"))
})
It("Should reject missing controlPlane configuration", func() {
By("Create GatewayProxy with missing controlPlane")
err := s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithMissingControlPlane, s.Namespace()))
Expect(err).To(HaveOccurred(), "creating GatewayProxy with missing controlPlane")
Expect(err.Error()).To(ContainSubstring("controlPlane must be specified when type is ControlPlane"))
})
It("Should accept valid provider configuration", func() {
By("Create GatewayProxy with valid provider")
err := s.CreateResourceFromString(fmt.Sprintf(gatewayProxyWithValidProvider, s.Namespace()))
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy with valid provider")
s.RetryAssertion(func() string {
gpYaml, _ := s.GetResourceYaml(types.KindGatewayProxy, s.Namespace())
return gpYaml
}).Should(ContainSubstring(`"type":"ControlPlane"`), "checking GatewayProxy is applied")
})
})
})