gateway api: support RouteNamespaces

Co-authored-by: Jean-Baptiste Doumenjou <925513+jbdoumenjou@users.noreply.github.com>
This commit is contained in:
Tom Moulard 2021-10-04 15:46:08 +02:00 committed by GitHub
parent 9ef3fc84f9
commit 969dd088a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 2629 additions and 95 deletions

View file

@ -55,19 +55,21 @@ type Client interface {
UpdateGatewayStatus(gateway *v1alpha1.Gateway, gatewayStatus v1alpha1.GatewayStatus) error
UpdateGatewayClassStatus(gatewayClass *v1alpha1.GatewayClass, condition metav1.Condition) error
GetGateways() []*v1alpha1.Gateway
GetHTTPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error)
GetTCPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error)
GetTLSRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error)
GetHTTPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error)
GetTCPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error)
GetTLSRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error)
GetService(namespace, name string) (*corev1.Service, bool, error)
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
GetNamespaces(selector labels.Selector) ([]string, error)
}
type clientWrapper struct {
csGateway versioned.Interface
csKube kubernetes.Interface
factoryNamespace informers.SharedInformerFactory
factoryGatewayClass externalversions.SharedInformerFactory
factoriesGateway map[string]externalversions.SharedInformerFactory
factoriesKube map[string]informers.SharedInformerFactory
@ -171,6 +173,9 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
options.LabelSelector = c.labelSelector
}
c.factoryNamespace = informers.NewSharedInformerFactory(c.csKube, resyncPeriod)
c.factoryNamespace.Core().V1().Namespaces().Informer().AddEventHandler(eventHandler)
c.factoryGatewayClass = externalversions.NewSharedInformerFactoryWithOptions(c.csGateway, resyncPeriod, externalversions.WithTweakListOptions(labelSelectorOptions))
c.factoryGatewayClass.Networking().V1alpha1().GatewayClasses().Informer().AddEventHandler(eventHandler)
@ -193,6 +198,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
c.factoriesSecret[ns] = factorySecret
}
c.factoryNamespace.Start(stopCh)
c.factoryGatewayClass.Start(stopCh)
for _, ns := range namespaces {
@ -201,6 +207,12 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
c.factoriesSecret[ns].Start(stopCh)
}
for t, ok := range c.factoryNamespace.WaitForCacheSync(stopCh) {
if !ok {
return nil, fmt.Errorf("timed out waiting for controller caches to sync %s", t.String())
}
}
for t, ok := range c.factoryGatewayClass.WaitForCacheSync(stopCh) {
if !ok {
return nil, fmt.Errorf("timed out waiting for controller caches to sync %s", t.String())
@ -230,53 +242,90 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
return eventCh, nil
}
func (c *clientWrapper) GetHTTPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error) {
if !c.isWatchedNamespace(namespace) {
return nil, fmt.Errorf("failed to get HTTPRoutes %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
}
httpRoutes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().HTTPRoutes().Lister().HTTPRoutes(namespace).List(selector)
func (c *clientWrapper) GetNamespaces(selector labels.Selector) ([]string, error) {
ns, err := c.factoryNamespace.Core().V1().Namespaces().Lister().List(selector)
if err != nil {
return nil, err
}
if len(httpRoutes) == 0 {
log.WithoutContext().Debugf("No HTTPRoutes found in %q namespace with labels selector %s", namespace, selector)
var namespaces []string
for _, namespace := range ns {
if !c.isWatchedNamespace(namespace.Name) {
log.WithoutContext().Warnf("Namespace %q is not within watched namespaces", selector, namespace)
continue
}
namespaces = append(namespaces, namespace.Name)
}
return namespaces, nil
}
func (c *clientWrapper) GetHTTPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.HTTPRoute, error) {
var httpRoutes []*v1alpha1.HTTPRoute
for _, namespace := range namespaces {
if !c.isWatchedNamespace(namespace) {
log.WithoutContext().Warnf("Failed to get HTTPRoutes with labels selector %s: %q is not within watched namespaces", selector, namespace)
continue
}
routes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().HTTPRoutes().Lister().HTTPRoutes(namespace).List(selector)
if err != nil {
return nil, err
}
if len(routes) == 0 {
log.WithoutContext().Debugf("No HTTPRoutes found in %q namespace with labels selector %s", namespace, selector)
continue
}
httpRoutes = append(httpRoutes, routes...)
}
return httpRoutes, nil
}
func (c *clientWrapper) GetTCPRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error) {
if !c.isWatchedNamespace(namespace) {
return nil, fmt.Errorf("failed to get TCPRoutes %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
}
func (c *clientWrapper) GetTCPRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TCPRoute, error) {
var tcpRoutes []*v1alpha1.TCPRoute
for _, namespace := range namespaces {
if !c.isWatchedNamespace(namespace) {
log.WithoutContext().Warnf("Failed to get TCPRoutes with labels selector %s: %q is not within watched namespaces", selector, namespace)
continue
}
tcpRoutes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TCPRoutes().Lister().TCPRoutes(namespace).List(selector)
if err != nil {
return nil, err
}
routes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TCPRoutes().Lister().TCPRoutes(namespace).List(selector)
if err != nil {
return nil, err
}
if len(tcpRoutes) == 0 {
log.WithoutContext().Debugf("No TCPRoutes found in %q namespace with labels selector %s", namespace, selector)
}
if len(routes) == 0 {
log.WithoutContext().Debugf("No TCPRoutes found in %q namespace with labels selector %s", namespace, selector)
continue
}
tcpRoutes = append(tcpRoutes, routes...)
}
return tcpRoutes, nil
}
func (c *clientWrapper) GetTLSRoutes(namespace string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error) {
if !c.isWatchedNamespace(namespace) {
return nil, fmt.Errorf("failed to get TLSRoutes %s with labels selector %s: namespace is not within watched namespaces", namespace, selector)
}
func (c *clientWrapper) GetTLSRoutes(namespaces []string, selector labels.Selector) ([]*v1alpha1.TLSRoute, error) {
var tlsRoutes []*v1alpha1.TLSRoute
for _, namespace := range namespaces {
if !c.isWatchedNamespace(namespace) {
log.WithoutContext().Warnf("Failed to get TLSRoutes with labels selector %s: %q is not within watched namespaces", selector, namespace)
continue
}
tlsRoutes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TLSRoutes().Lister().TLSRoutes(namespace).List(selector)
if err != nil {
return nil, err
}
routes, err := c.factoriesGateway[c.lookupNamespace(namespace)].Networking().V1alpha1().TLSRoutes().Lister().TLSRoutes(namespace).List(selector)
if err != nil {
return nil, err
}
if len(tlsRoutes) == 0 {
log.WithoutContext().Debugf("No TLSRoutes found in %q namespace with labels selector %s", namespace, selector)
}
if len(routes) == 0 {
log.WithoutContext().Debugf("No TLSRoutes found in %q namespace with labels selector %s", namespace, selector)
continue
}
tlsRoutes = append(tlsRoutes, routes...)
}
return tlsRoutes, nil
}