diff --git a/docs/tutorials/gateway-api.md b/docs/tutorials/gateway-api.md index cecab68c43..38da979e2b 100644 --- a/docs/tutorials/gateway-api.md +++ b/docs/tutorials/gateway-api.md @@ -8,7 +8,7 @@ It is meant to supplement the other provider-specific setup tutorials. As the Gateway API is still in an experimental phase, ExternalDNS makes no backwards compatibilty guarantees regarding its support. However, it currently supports a mixture of v1alpha2 and v1beta1 APIs. Gateways and HTTPRoutes are supported using the v1beta1 API. -TLSRoutes, TCPRoutes, and UDPRoutes are supported using the v1alpha2 API. +GRPCRoutes, TLSRoutes, TCPRoutes, and UDPRoutes are supported using the v1alpha2 API. ## Hostnames @@ -37,7 +37,7 @@ rules: resources: ["namespaces"] verbs: ["get","watch","list"] - apiGroups: ["gateway.networking.k8s.io"] - resources: ["gateways","httproutes","tlsroutes","tcproutes","udproutes"] + resources: ["gateways","httproutes","grpcroutes","tlsroutes","tcproutes","udproutes"] verbs: ["get","watch","list"] --- apiVersion: rbac.authorization.k8s.io/v1 @@ -76,6 +76,7 @@ spec: args: # Add desired Gateway API Route sources. - --source=gateway-httproute + - --source=gateway-grpcroute - --source=gateway-tlsroute - --source=gateway-tcproute - --source=gateway-udproute diff --git a/go.mod b/go.mod index b86a052c3b..ef33f05d54 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/prometheus/client_golang v1.12.2 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.1 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.550 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.344 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.550 @@ -72,7 +72,7 @@ require ( k8s.io/api v0.26.0 k8s.io/apimachinery v0.26.0 k8s.io/client-go v0.26.0 - sigs.k8s.io/gateway-api v0.5.1 + sigs.k8s.io/gateway-api v0.6.0 ) require ( @@ -163,7 +163,7 @@ require ( github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect github.com/smartystreets/gunit v1.3.4 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.4.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/terra-farm/udnssdk v1.3.5 // indirect github.com/vektah/gqlparser/v2 v2.5.0 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect @@ -172,13 +172,13 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect - golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/crypto v0.1.0 // indirect + golang.org/x/mod v0.6.0 // indirect golang.org/x/sys v0.3.0 // indirect golang.org/x/term v0.3.0 // indirect golang.org/x/text v0.5.0 // indirect golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/tools v0.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220804142021-4e6b2dfa6612 // indirect google.golang.org/grpc v1.48.0 // indirect diff --git a/go.sum b/go.sum index 4ab923c462..6ebf19bee6 100644 --- a/go.sum +++ b/go.sum @@ -1364,8 +1364,9 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1373,8 +1374,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.550 h1:Yni5V2K50ke+YAdq2Y2C0F8wrz2f4BM6WXQU2g+/m2Y= @@ -1561,8 +1563,9 @@ golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1614,8 +1617,9 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1986,8 +1990,9 @@ golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyj golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= @@ -2458,8 +2463,8 @@ sigs.k8s.io/controller-tools v0.6.0/go.mod h1:baRMVPrctU77F+rfAuH2uPqW93k6yQnZA2 sigs.k8s.io/controller-tools v0.6.2/go.mod h1:oaeGpjXn6+ZSEIQkUe/+3I40PNiDYp9aeawbt3xTgJ8= sigs.k8s.io/gateway-api v0.3.0/go.mod h1:Wb8bx7QhGVZxOSEU3i9vw/JqTB5Nlai9MLMYVZeDmRQ= sigs.k8s.io/gateway-api v0.4.3/go.mod h1:r3eiNP+0el+NTLwaTfOrCNXy8TukC+dIM3ggc+fbNWk= -sigs.k8s.io/gateway-api v0.5.1 h1:EqzgOKhChzyve9rmeXXbceBYB6xiM50vDfq0kK5qpdw= -sigs.k8s.io/gateway-api v0.5.1/go.mod h1:x0AP6gugkFV8fC/oTlnOMU0pnmuzIR8LfIPRVUjxSqA= +sigs.k8s.io/gateway-api v0.6.0 h1:v2FqrN2ROWZLrSnI2o91taHR8Sj3s+Eh3QU7gLNWIqA= +sigs.k8s.io/gateway-api v0.6.0/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 9b8597bb21..feef17557f 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -402,7 +402,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("skipper-routegroup-groupversion", "The resource version for skipper routegroup").Default(source.DefaultRoutegroupVersion).StringVar(&cfg.SkipperRouteGroupVersion) // Flags related to processing source - app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, gateway-httproute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress") + app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, node, fake, connector, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, istio-gateway, istio-virtualservice, cloudfoundry, contour-ingressroute, contour-httpproxy, gloo-proxy, crd, empty, skipper-routegroup, openshift-route, ambassador-host, kong-tcpingress)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "node", "pod", "gateway-httproute", "gateway-grpcroute", "gateway-tlsroute", "gateway-tcproute", "gateway-udproute", "istio-gateway", "istio-virtualservice", "cloudfoundry", "contour-ingressroute", "contour-httpproxy", "gloo-proxy", "fake", "connector", "crd", "empty", "skipper-routegroup", "openshift-route", "ambassador-host", "kong-tcpingress") app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName) app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace) app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter) diff --git a/source/gateway_grpcroute.go b/source/gateway_grpcroute.go new file mode 100644 index 0000000000..4f7c9d0237 --- /dev/null +++ b/source/gateway_grpcroute.go @@ -0,0 +1,57 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed 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 source + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/gateway-api/apis/v1alpha2" + "sigs.k8s.io/gateway-api/apis/v1beta1" + informers "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions" + informers_v1a2 "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions/apis/v1alpha2" +) + +// NewGatewayGRPCRouteSource creates a new Gateway GRPCRoute source with the given config. +func NewGatewayGRPCRouteSource(clients ClientGenerator, config *Config) (Source, error) { + return newGatewayRouteSource(clients, config, "GRPCRoute", func(factory informers.SharedInformerFactory) gatewayRouteInformer { + return &gatewayGRPCRouteInformer{factory.Gateway().V1alpha2().GRPCRoutes()} + }) +} + +type gatewayGRPCRoute struct{ route *v1alpha2.GRPCRoute } + +func (rt *gatewayGRPCRoute) Object() kubeObject { return rt.route } +func (rt *gatewayGRPCRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } +func (rt *gatewayGRPCRoute) Hostnames() []v1beta1.Hostname { return rt.route.Spec.Hostnames } +func (rt *gatewayGRPCRoute) Protocol() v1beta1.ProtocolType { return v1beta1.HTTPSProtocolType } +func (rt *gatewayGRPCRoute) RouteStatus() v1beta1.RouteStatus { return rt.route.Status.RouteStatus } + +type gatewayGRPCRouteInformer struct { + informers_v1a2.GRPCRouteInformer +} + +func (inf gatewayGRPCRouteInformer) List(namespace string, selector labels.Selector) ([]gatewayRoute, error) { + list, err := inf.GRPCRouteInformer.Lister().GRPCRoutes(namespace).List(selector) + if err != nil { + return nil, err + } + routes := make([]gatewayRoute, len(list)) + for i, rt := range list { + routes[i] = &gatewayGRPCRoute{rt} + } + return routes, nil +} diff --git a/source/gateway_grpcroute_test.go b/source/gateway_grpcroute_test.go new file mode 100644 index 0000000000..94250030dc --- /dev/null +++ b/source/gateway_grpcroute_test.go @@ -0,0 +1,98 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed 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 source + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kubefake "k8s.io/client-go/kubernetes/fake" + "sigs.k8s.io/external-dns/endpoint" + "sigs.k8s.io/gateway-api/apis/v1alpha2" + "sigs.k8s.io/gateway-api/apis/v1beta1" + gatewayfake "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/fake" +) + +func TestGatewayGRPCRouteSourceEndpoints(t *testing.T) { + t.Parallel() + + gwClient := gatewayfake.NewSimpleClientset() + kubeClient := kubefake.NewSimpleClientset() + clients := new(MockClientGenerator) + clients.On("GatewayClient").Return(gwClient, nil) + clients.On("KubeClient").Return(kubeClient, nil) + + ctx := context.Background() + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default", + }, + } + _, err := kubeClient.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) + require.NoError(t, err, "failed to create Namespace") + + ips := []string{"10.64.0.1", "10.64.0.2"} + gw := &v1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "internal", + Namespace: "default", + }, + Spec: v1beta1.GatewaySpec{ + Listeners: []v1beta1.Listener{{ + Protocol: v1beta1.HTTPSProtocolType, + }}, + }, + Status: gatewayStatus(ips...), + } + _, err = gwClient.GatewayV1beta1().Gateways(gw.Namespace).Create(ctx, gw, metav1.CreateOptions{}) + require.NoError(t, err, "failed to create Gateway") + + rt := &v1alpha2.GRPCRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "api", + Namespace: "default", + Annotations: map[string]string{ + hostnameAnnotationKey: "api-annotation.foobar.internal", + }, + }, + Spec: v1alpha2.GRPCRouteSpec{ + Hostnames: []v1alpha2.Hostname{"api-hostnames.foobar.internal"}, + }, + Status: v1alpha2.GRPCRouteStatus{ + RouteStatus: v1a2RouteStatus(v1a2ParentRef("default", "internal")), + }, + } + _, err = gwClient.GatewayV1alpha2().GRPCRoutes(rt.Namespace).Create(ctx, rt, metav1.CreateOptions{}) + require.NoError(t, err, "failed to create GRPCRoute") + + src, err := NewGatewayGRPCRouteSource(clients, &Config{ + FQDNTemplate: "{{.Name}}-template.foobar.internal", + CombineFQDNAndAnnotation: true, + }) + require.NoError(t, err, "failed to create Gateway GRPCRoute Source") + + endpoints, err := src.Endpoints(ctx) + require.NoError(t, err, "failed to get Endpoints") + validateEndpoints(t, endpoints, []*endpoint.Endpoint{ + newTestEndpoint("api-annotation.foobar.internal", "A", ips...), + newTestEndpoint("api-hostnames.foobar.internal", "A", ips...), + newTestEndpoint("api-template.foobar.internal", "A", ips...), + }) +} diff --git a/source/gateway_tcproute.go b/source/gateway_tcproute.go index 5badfaff12..34967324f4 100644 --- a/source/gateway_tcproute.go +++ b/source/gateway_tcproute.go @@ -34,13 +34,11 @@ func NewGatewayTCPRouteSource(clients ClientGenerator, config *Config) (Source, type gatewayTCPRoute struct{ route *v1alpha2.TCPRoute } -func (rt *gatewayTCPRoute) Object() kubeObject { return rt.route } -func (rt *gatewayTCPRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } -func (rt *gatewayTCPRoute) Hostnames() []v1beta1.Hostname { return nil } -func (rt *gatewayTCPRoute) Protocol() v1beta1.ProtocolType { return v1beta1.TCPProtocolType } -func (rt *gatewayTCPRoute) RouteStatus() v1beta1.RouteStatus { - return v1b1RouteStatus(rt.route.Status.RouteStatus) -} +func (rt *gatewayTCPRoute) Object() kubeObject { return rt.route } +func (rt *gatewayTCPRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } +func (rt *gatewayTCPRoute) Hostnames() []v1beta1.Hostname { return nil } +func (rt *gatewayTCPRoute) Protocol() v1beta1.ProtocolType { return v1beta1.TCPProtocolType } +func (rt *gatewayTCPRoute) RouteStatus() v1beta1.RouteStatus { return rt.route.Status.RouteStatus } type gatewayTCPRouteInformer struct { informers_v1a2.TCPRouteInformer @@ -57,50 +55,3 @@ func (inf gatewayTCPRouteInformer) List(namespace string, selector labels.Select } return routes, nil } - -func v1b1Hostnames(hostnames []v1alpha2.Hostname) []v1beta1.Hostname { - if len(hostnames) == 0 { - return nil - } - list := make([]v1beta1.Hostname, len(hostnames)) - for i, s := range hostnames { - list[i] = v1beta1.Hostname(s) - } - return list -} - -func v1b1RouteStatus(s v1alpha2.RouteStatus) v1beta1.RouteStatus { - return v1beta1.RouteStatus{ - Parents: v1b1RouteParentStatuses(s.Parents), - } -} - -func v1b1RouteParentStatuses(statuses []v1alpha2.RouteParentStatus) []v1beta1.RouteParentStatus { - if len(statuses) == 0 { - return nil - } - list := make([]v1beta1.RouteParentStatus, len(statuses)) - for i, s := range statuses { - list[i] = v1b1RouteParentStatus(s) - } - return list -} - -func v1b1RouteParentStatus(s v1alpha2.RouteParentStatus) v1beta1.RouteParentStatus { - return v1beta1.RouteParentStatus{ - ParentRef: v1b1ParentReference(s.ParentRef), - ControllerName: v1beta1.GatewayController(s.ControllerName), - Conditions: s.Conditions, - } -} - -func v1b1ParentReference(s v1alpha2.ParentReference) v1beta1.ParentReference { - return v1beta1.ParentReference{ - Group: (*v1beta1.Group)(s.Group), - Kind: (*v1beta1.Kind)(s.Kind), - Namespace: (*v1beta1.Namespace)(s.Namespace), - Name: v1beta1.ObjectName(s.Name), - SectionName: (*v1beta1.SectionName)(s.SectionName), - Port: (*v1beta1.PortNumber)(s.Port), - } -} diff --git a/source/gateway_tlsroute.go b/source/gateway_tlsroute.go index ec5de040e1..4602dd9753 100644 --- a/source/gateway_tlsroute.go +++ b/source/gateway_tlsroute.go @@ -34,15 +34,11 @@ func NewGatewayTLSRouteSource(clients ClientGenerator, config *Config) (Source, type gatewayTLSRoute struct{ route *v1alpha2.TLSRoute } -func (rt *gatewayTLSRoute) Object() kubeObject { return rt.route } -func (rt *gatewayTLSRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } -func (rt *gatewayTLSRoute) Hostnames() []v1beta1.Hostname { - return v1b1Hostnames(rt.route.Spec.Hostnames) -} -func (rt *gatewayTLSRoute) Protocol() v1beta1.ProtocolType { return v1beta1.TLSProtocolType } -func (rt *gatewayTLSRoute) RouteStatus() v1beta1.RouteStatus { - return v1b1RouteStatus(rt.route.Status.RouteStatus) -} +func (rt *gatewayTLSRoute) Object() kubeObject { return rt.route } +func (rt *gatewayTLSRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } +func (rt *gatewayTLSRoute) Hostnames() []v1beta1.Hostname { return rt.route.Spec.Hostnames } +func (rt *gatewayTLSRoute) Protocol() v1beta1.ProtocolType { return v1beta1.TLSProtocolType } +func (rt *gatewayTLSRoute) RouteStatus() v1beta1.RouteStatus { return rt.route.Status.RouteStatus } type gatewayTLSRouteInformer struct { informers_v1a2.TLSRouteInformer diff --git a/source/gateway_udproute.go b/source/gateway_udproute.go index 20ce5ccc43..4253a762cd 100644 --- a/source/gateway_udproute.go +++ b/source/gateway_udproute.go @@ -34,13 +34,11 @@ func NewGatewayUDPRouteSource(clients ClientGenerator, config *Config) (Source, type gatewayUDPRoute struct{ route *v1alpha2.UDPRoute } -func (rt *gatewayUDPRoute) Object() kubeObject { return rt.route } -func (rt *gatewayUDPRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } -func (rt *gatewayUDPRoute) Hostnames() []v1beta1.Hostname { return nil } -func (rt *gatewayUDPRoute) Protocol() v1beta1.ProtocolType { return v1beta1.UDPProtocolType } -func (rt *gatewayUDPRoute) RouteStatus() v1beta1.RouteStatus { - return v1b1RouteStatus(rt.route.Status.RouteStatus) -} +func (rt *gatewayUDPRoute) Object() kubeObject { return rt.route } +func (rt *gatewayUDPRoute) Metadata() *metav1.ObjectMeta { return &rt.route.ObjectMeta } +func (rt *gatewayUDPRoute) Hostnames() []v1beta1.Hostname { return nil } +func (rt *gatewayUDPRoute) Protocol() v1beta1.ProtocolType { return v1beta1.UDPProtocolType } +func (rt *gatewayUDPRoute) RouteStatus() v1beta1.RouteStatus { return rt.route.Status.RouteStatus } type gatewayUDPRouteInformer struct { informers_v1a2.UDPRouteInformer diff --git a/source/store.go b/source/store.go index 1f99f804df..87ba403a2d 100644 --- a/source/store.go +++ b/source/store.go @@ -229,6 +229,8 @@ func BuildWithConfig(ctx context.Context, source string, p ClientGenerator, cfg return NewPodSource(ctx, client, cfg.Namespace, cfg.Compatibility) case "gateway-httproute": return NewGatewayHTTPRouteSource(p, cfg) + case "gateway-grpcroute": + return NewGatewayGRPCRouteSource(p, cfg) case "gateway-tlsroute": return NewGatewayTLSRouteSource(p, cfg) case "gateway-tcproute":