Skip to content

Commit 3f41918

Browse files
Move route host updating out of the unique_host plugin
Because we are now using the informer cache, having the plugins mutate the passed in object is incorrect (the cache doesn't have that modification). Instead, mutate the cache from the very beginning so that we always have the router's preferred spec.host set.
1 parent 1d240ac commit 3f41918

File tree

8 files changed

+79
-37
lines changed

8 files changed

+79
-37
lines changed

pkg/cmd/infra/router/f5.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ func (o *F5RouterOptions) Run() error {
233233
}
234234

235235
factory := o.RouterSelection.NewFactory(routeclient, projectclient.Project().Projects(), kc)
236+
factory.RouteModifierFn = o.RouteUpdate
236237

237238
var plugin router.Plugin = f5Plugin
238239
var recorder controller.RejectionRecorder = controller.LogRejections
@@ -250,7 +251,7 @@ func (o *F5RouterOptions) Run() error {
250251
if o.ExtendedValidation {
251252
plugin = controller.NewExtendedValidator(plugin, recorder)
252253
}
253-
plugin = controller.NewUniqueHost(plugin, o.RouteSelectionFunc(), o.RouterSelection.DisableNamespaceOwnershipCheck, recorder)
254+
plugin = controller.NewUniqueHost(plugin, o.RouterSelection.DisableNamespaceOwnershipCheck, recorder)
254255
plugin = controller.NewHostAdmitter(plugin, o.F5RouteAdmitterFunc(), o.AllowWildcardRoutes, o.RouterSelection.DisableNamespaceOwnershipCheck, recorder)
255256

256257
watchNodes := (len(o.InternalAddress) != 0 && len(o.VxlanGateway) != 0)

pkg/cmd/infra/router/router.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -86,30 +86,31 @@ func (o *RouterSelection) Bind(flag *pflag.FlagSet) {
8686
flag.StringVar(&o.ListenAddr, "listen-addr", cmdutil.Env("ROUTER_LISTEN_ADDR", ""), "The name of an interface to listen on to expose metrics and health checking. If not specified, will not listen. Overrides stats port.")
8787
}
8888

89-
// RouteSelectionFunc returns a func that identifies the host for a route.
90-
func (o *RouterSelection) RouteSelectionFunc() controller.RouteHostFunc {
89+
// RouteUpdate updates the route before it is seen by the cache.
90+
func (o *RouterSelection) RouteUpdate(route *routeapi.Route) {
9191
if len(o.HostnameTemplate) == 0 {
92-
return controller.HostForRoute
92+
return
9393
}
94-
return func(route *routeapi.Route) string {
95-
if !o.OverrideHostname && len(route.Spec.Host) > 0 {
96-
return route.Spec.Host
97-
}
98-
s, err := variable.ExpandStrict(o.HostnameTemplate, func(key string) (string, bool) {
99-
switch key {
100-
case "name":
101-
return route.Name, true
102-
case "namespace":
103-
return route.Namespace, true
104-
default:
105-
return "", false
106-
}
107-
})
108-
if err != nil {
109-
return ""
94+
if !o.OverrideHostname && len(route.Spec.Host) > 0 {
95+
return
96+
}
97+
s, err := variable.ExpandStrict(o.HostnameTemplate, func(key string) (string, bool) {
98+
switch key {
99+
case "name":
100+
return route.Name, true
101+
case "namespace":
102+
return route.Namespace, true
103+
default:
104+
return "", false
110105
}
111-
return strings.Trim(s, "\"'")
106+
})
107+
if err != nil {
108+
return
112109
}
110+
111+
s = strings.Trim(s, "\"'")
112+
glog.V(4).Infof("changing route %s to %s", route.Spec.Host, s)
113+
route.Spec.Host = s
113114
}
114115

115116
func (o *RouterSelection) AdmissionCheck(route *routeapi.Route) error {

pkg/cmd/infra/router/template.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ func (o *TemplateRouterOptions) Run() error {
414414
}
415415

416416
factory := o.RouterSelection.NewFactory(routeclient, projectclient.Project().Projects(), kc)
417+
factory.RouteModifierFn = o.RouteUpdate
417418

418419
var plugin router.Plugin = templatePlugin
419420
var recorder controller.RejectionRecorder = controller.LogRejections
@@ -431,7 +432,7 @@ func (o *TemplateRouterOptions) Run() error {
431432
if o.ExtendedValidation {
432433
plugin = controller.NewExtendedValidator(plugin, recorder)
433434
}
434-
plugin = controller.NewUniqueHost(plugin, o.RouteSelectionFunc(), o.RouterSelection.DisableNamespaceOwnershipCheck, recorder)
435+
plugin = controller.NewUniqueHost(plugin, o.RouterSelection.DisableNamespaceOwnershipCheck, recorder)
435436
plugin = controller.NewHostAdmitter(plugin, o.RouteAdmissionFunc(), o.AllowWildcardRoutes, o.RouterSelection.DisableNamespaceOwnershipCheck, recorder)
436437

437438
controller := factory.Create(plugin, false)

pkg/router/controller/factory/factory.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type RouterControllerFactory struct {
4545
FieldSelector string
4646
NamespaceLabels labels.Selector
4747
ProjectLabels labels.Selector
48+
RouteModifierFn func(route *routeapi.Route)
4849

4950
informers map[reflect.Type]kcache.SharedIndexInformer
5051
}
@@ -122,6 +123,7 @@ func (f *RouterControllerFactory) registerInformerEventHandlers(rc *routercontro
122123
f.registerSharedInformerEventHandlers(&kapi.Namespace{}, rc.HandleNamespace)
123124
}
124125
f.registerSharedInformerEventHandlers(&kapi.Endpoints{}, rc.HandleEndpoints)
126+
125127
f.registerSharedInformerEventHandlers(&routeapi.Route{}, rc.HandleRoute)
126128

127129
if rc.WatchNodes {
@@ -218,13 +220,30 @@ func (f *RouterControllerFactory) CreateRoutesSharedInformer() kcache.SharedInde
218220
if err != nil {
219221
return nil, err
220222
}
223+
if f.RouteModifierFn != nil {
224+
for i := range routeList.Items {
225+
f.RouteModifierFn(&routeList.Items[i])
226+
}
227+
}
221228
// Return routes in order of age to avoid rejections during resync
222229
sort.Sort(routeAge(routeList.Items))
223230
return routeList, nil
224231
},
225232
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
226233
f.setSelectors(&options)
227-
return f.RClient.Route().Routes(f.Namespace).Watch(options)
234+
w, err := f.RClient.Route().Routes(f.Namespace).Watch(options)
235+
if err != nil {
236+
return nil, err
237+
}
238+
if f.RouteModifierFn != nil {
239+
watch.Filter(w, func(in watch.Event) (watch.Event, bool) {
240+
if route, ok := in.Object.(*routeapi.Route); ok {
241+
f.RouteModifierFn(route)
242+
}
243+
return in, true
244+
})
245+
}
246+
return w, nil
228247
},
229248
}
230249
indexers := kcache.Indexers{kcache.NamespaceIndex: kcache.MetaNamespaceIndexFunc}

pkg/router/controller/host_admitter_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ func TestDisableOwnershipChecksFuzzing(t *testing.T) {
854854

855855
admitAll := func(route *routeapi.Route) error { return nil }
856856
recorder := rejectionRecorder{rejections: make(map[string]string)}
857-
uniqueHostPlugin := NewUniqueHost(p, HostForRoute, true, recorder)
857+
uniqueHostPlugin := NewUniqueHost(p, true, recorder)
858858
admitter := NewHostAdmitter(uniqueHostPlugin, RouteAdmissionFunc(admitAll), true, true, recorder)
859859

860860
oldest := metav1.Time{Time: time.Now()}

pkg/router/controller/status_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,23 @@ func TestStatusResetsHost(t *testing.T) {
235235
admitter := NewStatusAdmitter(p, c.Route(), lister, "test", "", noopLease{}, tracker)
236236
err := admitter.HandleRoute(watch.Added, route)
237237

238-
checkResult(t, err, c, admitter, "route1.test.local", now, &now.Time, 0, 0)
238+
route = checkResult(t, err, c, admitter, "route1.test.local", now, &now.Time, 0, 0)
239+
ingress := findIngressForRoute(route, "test")
240+
if ingress == nil {
241+
t.Fatalf("no ingress found: %#v", route)
242+
}
243+
if ingress.Host != "route1.test.local" {
244+
t.Fatalf("incorrect ingress: %#v", ingress)
245+
}
246+
}
247+
248+
func findIngressForRoute(route *routeapi.Route, routerName string) *routeapi.RouteIngress {
249+
for i := range route.Status.Ingress {
250+
if route.Status.Ingress[i].RouterName == routerName {
251+
return &route.Status.Ingress[i]
252+
}
253+
}
254+
return nil
239255
}
240256

241257
func TestStatusAdmitsRouteOnForbidden(t *testing.T) {
@@ -273,7 +289,14 @@ func TestStatusAdmitsRouteOnForbidden(t *testing.T) {
273289
lister := &routeLister{items: []*routeapi.Route{route}}
274290
admitter := NewStatusAdmitter(p, c.Route(), lister, "test", "", noopLease{}, tracker)
275291
err := admitter.HandleRoute(watch.Added, route)
276-
checkResult(t, err, c, admitter, "route1.test.local", now, &touched.Time, 0, 0)
292+
route = checkResult(t, err, c, admitter, "route1.test.local", now, &touched.Time, 0, 0)
293+
ingress := findIngressForRoute(route, "test")
294+
if ingress == nil {
295+
t.Fatalf("no ingress found: %#v", route)
296+
}
297+
if ingress.Host != "route1.test.local" {
298+
t.Fatalf("incorrect ingress: %#v", ingress)
299+
}
277300
}
278301

279302
func TestStatusBackoffOnConflict(t *testing.T) {

pkg/router/controller/unique_host.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ func HostForRoute(route *routeapi.Route) string {
2727
// UniqueHost implements the router.Plugin interface to provide
2828
// a template based, backend-agnostic router.
2929
type UniqueHost struct {
30-
plugin router.Plugin
31-
hostForRoute RouteHostFunc
30+
plugin router.Plugin
3231

3332
recorder RejectionRecorder
3433

@@ -43,14 +42,13 @@ type UniqueHost struct {
4342
// NewUniqueHost creates a plugin wrapper that ensures only unique routes are passed into
4443
// the underlying plugin. Recorder is an interface for indicating why a route was
4544
// rejected.
46-
func NewUniqueHost(plugin router.Plugin, fn RouteHostFunc, disableOwnershipCheck bool, recorder RejectionRecorder) *UniqueHost {
45+
func NewUniqueHost(plugin router.Plugin, disableOwnershipCheck bool, recorder RejectionRecorder) *UniqueHost {
4746
routeActivationFn := hostindex.SameNamespace
4847
if disableOwnershipCheck {
4948
routeActivationFn = hostindex.OldestFirst
5049
}
5150
return &UniqueHost{
52-
plugin: plugin,
53-
hostForRoute: fn,
51+
plugin: plugin,
5452

5553
recorder: recorder,
5654

@@ -92,15 +90,14 @@ func (p *UniqueHost) HandleRoute(eventType watch.EventType, route *routeapi.Rout
9290
}
9391

9492
routeName := routeNameKey(route)
93+
host := route.Spec.Host
9594

96-
host := p.hostForRoute(route)
9795
if len(host) == 0 {
9896
glog.V(4).Infof("Route %s has no host value", routeName)
9997
p.recorder.RecordRouteRejection(route, "NoHostValue", "no host value was defined for the route")
10098
p.plugin.HandleRoute(watch.Deleted, route)
10199
return nil
102100
}
103-
route.Spec.Host = host
104101

105102
// Validate that the route host name conforms to DNS requirements.
106103
// Defends against routes created before validation rules were added for host names.

pkg/router/template/plugin_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ func TestHandleEndpoints(t *testing.T) {
332332
templatePlugin := newDefaultTemplatePlugin(router, true, nil)
333333
// TODO: move tests that rely on unique hosts to pkg/router/controller and remove them from
334334
// here
335-
plugin := controller.NewUniqueHost(templatePlugin, controller.HostForRoute, false, controller.LogRejections)
335+
plugin := controller.NewUniqueHost(templatePlugin, false, controller.LogRejections)
336336

337337
for _, tc := range testCases {
338338
plugin.HandleEndpoints(tc.eventType, tc.endpoints)
@@ -442,7 +442,7 @@ func TestHandleTCPEndpoints(t *testing.T) {
442442
templatePlugin := newDefaultTemplatePlugin(router, false, nil)
443443
// TODO: move tests that rely on unique hosts to pkg/router/controller and remove them from
444444
// here
445-
plugin := controller.NewUniqueHost(templatePlugin, controller.HostForRoute, false, controller.LogRejections)
445+
plugin := controller.NewUniqueHost(templatePlugin, false, controller.LogRejections)
446446

447447
for _, tc := range testCases {
448448
plugin.HandleEndpoints(tc.eventType, tc.endpoints)
@@ -484,7 +484,7 @@ func TestHandleRoute(t *testing.T) {
484484
templatePlugin := newDefaultTemplatePlugin(router, true, nil)
485485
// TODO: move tests that rely on unique hosts to pkg/router/controller and remove them from
486486
// here
487-
plugin := controller.NewUniqueHost(templatePlugin, controller.HostForRoute, false, rejections)
487+
plugin := controller.NewUniqueHost(templatePlugin, false, rejections)
488488

489489
uidCount := 0
490490
nextUID := func() types.UID {
@@ -1033,7 +1033,7 @@ func TestNamespaceScopingFromEmpty(t *testing.T) {
10331033
templatePlugin := newDefaultTemplatePlugin(router, true, nil)
10341034
// TODO: move tests that rely on unique hosts to pkg/router/controller and remove them from
10351035
// here
1036-
plugin := controller.NewUniqueHost(templatePlugin, controller.HostForRoute, false, controller.LogRejections)
1036+
plugin := controller.NewUniqueHost(templatePlugin, false, controller.LogRejections)
10371037

10381038
// no namespaces allowed
10391039
plugin.HandleNamespaces(sets.String{})

0 commit comments

Comments
 (0)