Skip to content

Commit

Permalink
Move CRD informer list generation to k8s (#2352)
Browse files Browse the repository at this point in the history
This is in preparation for adding in filtering by discovered CRD types.

Updates #2219

Signed-off-by: Nick Young <[email protected]>
  • Loading branch information
Nick Young authored Mar 23, 2020
1 parent b18ef08 commit b418f92
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 25 deletions.
32 changes: 11 additions & 21 deletions cmd/contour/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ import (
"syscall"
"time"

projectcontour "github.com/projectcontour/contour/apis/projectcontour/v1"

ingressroutev1 "github.com/projectcontour/contour/apis/contour/v1beta1"

serviceapis "sigs.k8s.io/service-apis/api/v1alpha1"

"github.com/projectcontour/contour/internal/contour"
"github.com/projectcontour/contour/internal/dag"
"github.com/projectcontour/contour/internal/debug"
Expand Down Expand Up @@ -206,30 +200,26 @@ func doServe(log logrus.FieldLogger, ctx *serveContext) error {
// using the SyncList to keep track of what to sync later.
var informerSyncList k8s.InformerSyncList

informerSyncList.Add(dynamicInformerFactory.ForResource(ingressroutev1.IngressRouteGVR).Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(dynamicInformerFactory.ForResource(ingressroutev1.TLSCertificateDelegationGVR).Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(dynamicInformerFactory.ForResource(projectcontour.HTTPProxyGVR).Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(dynamicInformerFactory.ForResource(projectcontour.TLSCertificateDelegationGVR).Informer()).AddEventHandler(dynamicHandler)
iset := k8s.DefaultInformerSet(dynamicInformerFactory, ctx.UseExperimentalServiceAPITypes)

informerSyncList.Add(informerFactory.Core().V1().Services().Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(informerFactory.Networking().V1beta1().Ingresses().Informer()).AddEventHandler(dynamicHandler)
// TODO(youngnick): Add in filtering the iset map by enabled apiserver types (#2219) using the discovery library.

if ctx.UseExperimentalServiceAPITypes {
log.Info("Enabling Experimental Service APIs types")
informerSyncList.Add(dynamicInformerFactory.ForResource(serviceapis.GroupVersion.WithResource("gatewayclasses")).Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(dynamicInformerFactory.ForResource(serviceapis.GroupVersion.WithResource("gateways")).Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(dynamicInformerFactory.ForResource(serviceapis.GroupVersion.WithResource("httproutes")).Informer()).AddEventHandler(dynamicHandler)
informerSyncList.Add(dynamicInformerFactory.ForResource(serviceapis.GroupVersion.WithResource("tcproutes")).Informer()).AddEventHandler(dynamicHandler)
for _, inf := range iset.Informers {
informerSyncList.RegisterInformer(inf, dynamicHandler)
}

// We need to register this separately for now, as the core stuff uses a non-dynamic InformerFactory.
informerSyncList.RegisterInformer(informerFactory.Core().V1().Services().Informer(), dynamicHandler)
informerSyncList.RegisterInformer(informerFactory.Networking().V1beta1().Ingresses().Informer(), dynamicHandler)

// Add informers for each root-ingressroute namespaces
for _, factory := range namespacedInformerFactories {
informerSyncList.Add(factory.Core().V1().Secrets().Informer()).AddEventHandler(dynamicHandler)
informerSyncList.RegisterInformer(factory.Core().V1().Secrets().Informer(), dynamicHandler)
}

// If root-ingressroutes are not defined, then add the informer for all namespaces
if len(namespacedInformerFactories) == 0 {
informerSyncList.Add(informerFactory.Core().V1().Secrets().Informer()).AddEventHandler(dynamicHandler)
informerSyncList.RegisterInformer(informerFactory.Core().V1().Secrets().Informer(), dynamicHandler)
}

// step 5. endpoints updates are handled directly by the EndpointsTranslator
Expand All @@ -238,7 +228,7 @@ func doServe(log logrus.FieldLogger, ctx *serveContext) error {
FieldLogger: log.WithField("context", "endpointstranslator"),
}

informerSyncList.Add(informerFactory.Core().V1().Endpoints().Informer()).AddEventHandler(et)
informerSyncList.RegisterInformer(informerFactory.Core().V1().Endpoints().Informer(), et)

// step 6. setup workgroup runner and register informers.
var g workgroup.Group
Expand Down
62 changes: 62 additions & 0 deletions internal/k8s/informers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright © 2020 VMware
// 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 k8s

import (
projectcontour "github.com/projectcontour/contour/apis/projectcontour/v1"

ingressroutev1 "github.com/projectcontour/contour/apis/contour/v1beta1"

serviceapis "sigs.k8s.io/service-apis/api/v1alpha1"

"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/tools/cache"
)

type gvrmap map[schema.GroupVersionResource]cache.SharedIndexInformer

// InformerSet stores a table of Kubernetes GVR objects to their associated informers.
type InformerSet struct {
Informers gvrmap
}

// DefaultInformerSet creates a new InformerSet lookup table and populates with the default
// GVRs that Contour will try to watch.
func DefaultInformerSet(inffactory dynamicinformer.DynamicSharedInformerFactory, serviceAPIs bool) InformerSet {

defaultGVRs := []schema.GroupVersionResource{
ingressroutev1.IngressRouteGVR,
ingressroutev1.TLSCertificateDelegationGVR,
projectcontour.HTTPProxyGVR,
projectcontour.TLSCertificateDelegationGVR,
}

// TODO(youngnick): Remove this boolean once we have autodetection of available types (Further work on #2219).
if serviceAPIs {
defaultGVRs = append(defaultGVRs, serviceapis.GroupVersion.WithResource("gatewayclasses"))
defaultGVRs = append(defaultGVRs, serviceapis.GroupVersion.WithResource("gateways"))
defaultGVRs = append(defaultGVRs, serviceapis.GroupVersion.WithResource("httproutes"))
defaultGVRs = append(defaultGVRs, serviceapis.GroupVersion.WithResource("tcproutes"))
}

gvri := InformerSet{
Informers: make(gvrmap),
}

for _, gvr := range defaultGVRs {
gvri.Informers[gvr] = inffactory.ForResource(gvr).Informer()
}
return gvri
}
8 changes: 4 additions & 4 deletions internal/k8s/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ type InformerSyncList struct {
syncers []cache.InformerSynced
}

// Add adds the sync function from an informer to InformerSyncList and returns the informer
// so that .AddEventHandler() can be called on it.
func (sl *InformerSyncList) Add(inf cache.SharedIndexInformer) cache.SharedIndexInformer {
// RegisterInformer adds the sync function from an informer to InformerSyncList and calls the informers
// AddEventHandler method.
func (sl *InformerSyncList) RegisterInformer(inf cache.SharedIndexInformer, handler cache.ResourceEventHandler) {
sl.syncers = append(sl.syncers, inf.HasSynced)
return inf
inf.AddEventHandler(handler)
}

// WaitForSync ensures that all the informers in the InformerSyncList are synced before returning.
Expand Down

0 comments on commit b418f92

Please sign in to comment.