feat: adds conformance test gateway api

This commit is contained in:
Michael 2024-01-22 15:30:05 +01:00 committed by GitHub
parent f57cee578f
commit 5e0855ecc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 333 additions and 15 deletions

37
.github/workflows/test-conformance.yaml vendored Normal file
View file

@ -0,0 +1,37 @@
name: Test K8s Gateway API conformance
on:
pull_request:
branches:
- '*'
paths:
- 'pkg/provider/kubernetes/gateway'
env:
GO_VERSION: '1.21'
CGO_ENABLED: 0
jobs:
test-conformance:
runs-on: ubuntu-20.04
steps:
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Avoid generating webui
run: touch webui/static/index.html
- name: Build binary
run: make binary
- name: K8s Gateway API conformance test
run: sudo make test-gateway-api-conformance

View file

@ -4,9 +4,6 @@ on:
pull_request:
branches:
- '*'
push:
branches:
- 'gh-actions'
env:
GO_VERSION: '1.21'

1
.gitignore vendored
View file

@ -19,3 +19,4 @@ plugins-storage/
plugins-local/
traefik_changelog.md
integration/tailscale.secret
integration/conformance-reports/

View file

@ -99,6 +99,11 @@ test-unit:
test-integration: binary
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -test.timeout=20m -failfast -v $(TESTFLAGS)
## Run the conformance tests
.PHONY: test-gateway-api-conformance
test-gateway-api-conformance: binary
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -v -test.run K8sConformanceSuite -k8sConformance=true $(TESTFLAGS)
## Pull all Docker images to avoid timeout during integration tests
.PHONY: pull-images
pull-images:

10
go.mod
View file

@ -85,12 +85,13 @@ require (
golang.org/x/tools v0.14.0
google.golang.org/grpc v1.59.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.28.3
k8s.io/api v0.28.4
k8s.io/apiextensions-apiserver v0.28.3
k8s.io/apimachinery v0.28.3
k8s.io/client-go v0.28.3
k8s.io/apimachinery v0.28.4
k8s.io/client-go v0.28.4
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
mvdan.cc/xurls/v2 v2.5.0
sigs.k8s.io/controller-runtime v0.16.3
sigs.k8s.io/gateway-api v1.0.0
)
@ -162,6 +163,7 @@ require (
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.7.0 // indirect
github.com/exoscale/egoscale v0.100.1 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
@ -236,6 +238,7 @@ require (
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@ -254,7 +257,6 @@ require (
github.com/nzdjb/go-metaname v1.0.0 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/onsi/gomega v1.27.10 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.5 // indirect

24
go.sum
View file

@ -114,6 +114,8 @@ github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJ
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
@ -302,6 +304,8 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc=
github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
github.com/exoscale/egoscale v0.100.1 h1:iXsV1Ei7daqe/6FYSCSDyrFs1iUG1l1X9qNh2uMw6z0=
github.com/exoscale/egoscale v0.100.1/go.mod h1:BAb9p4rmyU+Wl400CJZO5270H2sXtdsZjLcm5xMKkz4=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@ -358,6 +362,8 @@ github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
@ -796,6 +802,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
@ -1485,6 +1493,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
@ -1619,14 +1629,14 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=
k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo=
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
@ -1640,6 +1650,8 @@ nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs=
sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=

View file

@ -0,0 +1,21 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
noColor = true
[api]
insecure = true
[experimental]
kubernetesGateway = true
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[providers.kubernetesGateway]

View file

@ -35,7 +35,11 @@ import (
"gopkg.in/yaml.v3"
)
var showLog = flag.Bool("tlog", false, "always show Traefik logs")
var (
showLog = flag.Bool("tlog", false, "always show Traefik logs")
k8sConformance = flag.Bool("k8sConformance", false, "run K8s Gateway API conformance test")
k8sConformanceRunTest = flag.String("k8sConformanceRunTest", "", "run a specific K8s Gateway API conformance test")
)
const tailscaleSecretFilePath = "tailscale.secret"

View file

@ -0,0 +1,229 @@
package integration
import (
"context"
"fmt"
"net"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/traefik/traefik/v3/integration/try"
"github.com/traefik/traefik/v3/pkg/version"
"gopkg.in/yaml.v3"
ktypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
kclientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"
gatev1 "sigs.k8s.io/gateway-api/apis/v1"
gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatev1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
conformanceV1alpha1 "sigs.k8s.io/gateway-api/conformance/apis/v1alpha1"
"sigs.k8s.io/gateway-api/conformance/tests"
"sigs.k8s.io/gateway-api/conformance/utils/config"
ksuite "sigs.k8s.io/gateway-api/conformance/utils/suite"
)
// K8sConformanceSuite tests suite.
type K8sConformanceSuite struct{ BaseSuite }
func TestK8sConformanceSuite(t *testing.T) {
suite.Run(t, new(K8sConformanceSuite))
}
func (s *K8sConformanceSuite) SetupSuite() {
s.BaseSuite.SetupSuite()
s.createComposeProject("k8s")
s.composeUp()
abs, err := filepath.Abs("./fixtures/k8s/config.skip/kubeconfig.yaml")
require.NoError(s.T(), err)
err = try.Do(60*time.Second, func() error {
_, err := os.Stat(abs)
return err
})
require.NoError(s.T(), err)
data, err := os.ReadFile(abs)
require.NoError(s.T(), err)
content := strings.ReplaceAll(string(data), "https://server:6443", fmt.Sprintf("https://%s", net.JoinHostPort(s.getComposeServiceIP("server"), "6443")))
err = os.WriteFile(abs, []byte(content), 0o644)
require.NoError(s.T(), err)
err = os.Setenv("KUBECONFIG", abs)
require.NoError(s.T(), err)
}
func (s *K8sConformanceSuite) TearDownSuite() {
s.BaseSuite.TearDownSuite()
generatedFiles := []string{
"./fixtures/k8s/config.skip/kubeconfig.yaml",
"./fixtures/k8s/config.skip/k3s.log",
"./fixtures/k8s/rolebindings.yaml",
"./fixtures/k8s/ccm.yaml",
}
for _, filename := range generatedFiles {
if err := os.Remove(filename); err != nil {
log.Warn().Err(err).Send()
}
}
}
func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() {
if !*k8sConformance {
s.T().Skip("Skip because it can take a long time to execute. To enable pass the `k8sConformance` flag.")
}
configFromFlags, err := clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG"))
if err != nil {
s.T().Fatal(err)
}
kClient, err := client.New(configFromFlags, client.Options{})
if err != nil {
s.T().Fatalf("Error initializing Kubernetes client: %v", err)
}
kClientSet, err := kclientset.NewForConfig(configFromFlags)
if err != nil {
s.T().Fatal(err)
}
err = gatev1alpha2.AddToScheme(kClient.Scheme())
require.NoError(s.T(), err)
err = gatev1beta1.AddToScheme(kClient.Scheme())
require.NoError(s.T(), err)
err = gatev1.AddToScheme(kClient.Scheme())
require.NoError(s.T(), err)
s.traefikCmd(withConfigFile("fixtures/k8s_gateway_conformance.toml"))
// Wait for traefik to start
err = try.GetRequest("http://127.0.0.1:8080/api/entrypoints", 10*time.Second, try.BodyContains(`"name":"web"`))
require.NoError(s.T(), err)
err = try.Do(10*time.Second, func() error {
gwc := &gatev1.GatewayClass{}
err := kClient.Get(context.Background(), ktypes.NamespacedName{Name: "my-gateway-class"}, gwc)
if err != nil {
return fmt.Errorf("error fetching GatewayClass: %w", err)
}
return nil
})
require.NoError(s.T(), err)
opts := ksuite.Options{
Client: kClient,
RestConfig: configFromFlags,
Clientset: kClientSet,
GatewayClassName: "my-gateway-class",
Debug: true,
CleanupBaseResources: true,
TimeoutConfig: config.TimeoutConfig{
CreateTimeout: 5 * time.Second,
DeleteTimeout: 5 * time.Second,
GetTimeout: 5 * time.Second,
GatewayMustHaveAddress: 5 * time.Second,
GatewayMustHaveCondition: 5 * time.Second,
GatewayStatusMustHaveListeners: 10 * time.Second,
GatewayListenersMustHaveCondition: 5 * time.Second,
GWCMustBeAccepted: 60 * time.Second, // Pod creation in k3s cluster can be long.
HTTPRouteMustNotHaveParents: 5 * time.Second,
HTTPRouteMustHaveCondition: 5 * time.Second,
TLSRouteMustHaveCondition: 5 * time.Second,
RouteMustHaveParents: 5 * time.Second,
ManifestFetchTimeout: 5 * time.Second,
MaxTimeToConsistency: 5 * time.Second,
NamespacesMustBeReady: 60 * time.Second, // Pod creation in k3s cluster can be long.
RequestTimeout: 5 * time.Second,
LatestObservedGenerationSet: 5 * time.Second,
RequiredConsecutiveSuccesses: 0,
},
SupportedFeatures: sets.New[ksuite.SupportedFeature]().
Insert(ksuite.GatewayCoreFeatures.UnsortedList()...),
EnableAllSupportedFeatures: false,
RunTest: *k8sConformanceRunTest,
// Until the feature are all supported, following tests are skipped.
SkipTests: []string{
"HTTPExactPathMatching",
"HTTPRouteHostnameIntersection",
"GatewaySecretReferenceGrantAllInNamespace",
"HTTPRouteListenerHostnameMatching",
"HTTPRouteRequestHeaderModifier",
"GatewaySecretInvalidReferenceGrant",
"GatewayClassObservedGenerationBump",
"HTTPRouteInvalidNonExistentBackendRef",
"GatewayWithAttachedRoutes",
"HTTPRouteCrossNamespace",
"HTTPRouteDisallowedKind",
"HTTPRouteInvalidReferenceGrant",
"HTTPRouteObservedGenerationBump",
"GatewayInvalidRouteKind",
"TLSRouteSimpleSameNamespace",
"TLSRouteInvalidReferenceGrant",
"HTTPRouteInvalidCrossNamespaceParentRef",
"HTTPRouteInvalidParentRefNotMatchingSectionName",
"GatewaySecretReferenceGrantSpecific",
"GatewayModifyListeners",
"GatewaySecretMissingReferenceGrant",
"GatewayInvalidTLSConfiguration",
"HTTPRouteInvalidCrossNamespaceBackendRef",
"HTTPRouteMatchingAcrossRoutes",
"HTTPRoutePartiallyInvalidViaInvalidReferenceGrant",
"HTTPRouteRedirectHostAndStatus",
"HTTPRouteInvalidBackendRefUnknownKind",
"HTTPRoutePathMatchOrder",
"HTTPRouteSimpleSameNamespace",
"HTTPRouteMatching",
"HTTPRouteHeaderMatching",
"HTTPRouteReferenceGrant",
},
}
cSuite, err := ksuite.NewExperimentalConformanceTestSuite(ksuite.ExperimentalConformanceOptions{
Options: opts,
Implementation: conformanceV1alpha1.Implementation{
Organization: "traefik",
Project: "traefik",
URL: "https://traefik.io/",
Version: version.Version,
Contact: []string{"@traefik/maintainers"},
},
ConformanceProfiles: sets.New[ksuite.ConformanceProfileName](
ksuite.HTTPConformanceProfileName,
ksuite.TLSConformanceProfileName,
),
})
require.NoError(s.T(), err)
cSuite.Setup(s.T())
err = cSuite.Run(s.T(), tests.ConformanceTests)
require.NoError(s.T(), err)
report, err := cSuite.Report()
require.NoError(s.T(), err, "failed generating conformance report")
report.GatewayAPIVersion = "1.0.0"
rawReport, err := yaml.Marshal(report)
require.NoError(s.T(), err)
s.T().Logf("Conformance report:\n%s", string(rawReport))
require.NoError(s.T(), os.MkdirAll("./conformance-reports", 0o755))
outFile := filepath.Join("conformance-reports", fmt.Sprintf("traefik-traefik-%d.yaml", time.Now().UnixNano()))
require.NoError(s.T(), os.WriteFile(outFile, rawReport, 0o600))
s.T().Logf("Report written to: %s", outFile)
}

View file

@ -230,6 +230,7 @@ func (p *Provider) loadConfigurationFromGateway(ctx context.Context, client Clie
err := client.UpdateGatewayClassStatus(gatewayClass, metav1.Condition{
Type: string(gatev1.GatewayClassConditionStatusAccepted),
Status: metav1.ConditionTrue,
ObservedGeneration: gatewayClass.Generation,
Reason: "Handled",
Message: "Handled by Traefik controller",
LastTransitionTime: metav1.Now(),
@ -587,7 +588,16 @@ func (p *Provider) makeGatewayStatus(gateway *gatev1.Gateway, listenerStatuses [
Type: string(gatev1.GatewayConditionAccepted),
Status: metav1.ConditionTrue,
ObservedGeneration: gateway.Generation,
Reason: string(gatev1.GatewayConditionAccepted),
Reason: string(gatev1.GatewayReasonAccepted),
Message: "Gateway successfully scheduled",
LastTransitionTime: metav1.Now(),
},
// update "Programmed" status with "Programmed" reason
metav1.Condition{
Type: string(gatev1.GatewayConditionProgrammed),
Status: metav1.ConditionTrue,
ObservedGeneration: gateway.Generation,
Reason: string(gatev1.GatewayReasonProgrammed),
Message: "Gateway successfully scheduled",
LastTransitionTime: metav1.Now(),
},