Skip to content

Commit 1ccbb6c

Browse files
author
OpenShift Bot
authored
Merge pull request #12416 from marun/ingress-configured-router
Merged by openshift-bot
2 parents 2a936b6 + 0e2fa74 commit 1ccbb6c

File tree

18 files changed

+1851
-48
lines changed

18 files changed

+1851
-48
lines changed

contrib/completions/bash/openshift

+4
Original file line numberDiff line numberDiff line change
@@ -20811,6 +20811,8 @@ _openshift_infra_f5-router()
2081120811
local_nonpersistent_flags+=("--denied-domains=")
2081220812
flags+=("--disable-namespace-ownership-check")
2081320813
local_nonpersistent_flags+=("--disable-namespace-ownership-check")
20814+
flags+=("--enable-ingress")
20815+
local_nonpersistent_flags+=("--enable-ingress")
2081420816
flags+=("--f5-host=")
2081520817
local_nonpersistent_flags+=("--f5-host=")
2081620818
flags+=("--f5-http-vserver=")
@@ -20996,6 +20998,8 @@ _openshift_infra_router()
2099620998
local_nonpersistent_flags+=("--denied-domains=")
2099720999
flags+=("--disable-namespace-ownership-check")
2099821000
local_nonpersistent_flags+=("--disable-namespace-ownership-check")
21001+
flags+=("--enable-ingress")
21002+
local_nonpersistent_flags+=("--enable-ingress")
2099921003
flags+=("--extended-validation")
2100021004
local_nonpersistent_flags+=("--extended-validation")
2100121005
flags+=("--fields=")

contrib/completions/zsh/openshift

+4
Original file line numberDiff line numberDiff line change
@@ -20959,6 +20959,8 @@ _openshift_infra_f5-router()
2095920959
local_nonpersistent_flags+=("--denied-domains=")
2096020960
flags+=("--disable-namespace-ownership-check")
2096120961
local_nonpersistent_flags+=("--disable-namespace-ownership-check")
20962+
flags+=("--enable-ingress")
20963+
local_nonpersistent_flags+=("--enable-ingress")
2096220964
flags+=("--f5-host=")
2096320965
local_nonpersistent_flags+=("--f5-host=")
2096420966
flags+=("--f5-http-vserver=")
@@ -21144,6 +21146,8 @@ _openshift_infra_router()
2114421146
local_nonpersistent_flags+=("--denied-domains=")
2114521147
flags+=("--disable-namespace-ownership-check")
2114621148
local_nonpersistent_flags+=("--disable-namespace-ownership-check")
21149+
flags+=("--enable-ingress")
21150+
local_nonpersistent_flags+=("--enable-ingress")
2114721151
flags+=("--extended-validation")
2114821152
local_nonpersistent_flags+=("--extended-validation")
2114921153
flags+=("--fields=")

docs/man/man1/openshift-infra-f5-router.1

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ You may restrict the set of routes exposed to a single project (with \-\-namespa
7171
\fB\-\-disable\-namespace\-ownership\-check\fP=false
7272
Disables the namespace ownership checks for a route host with different paths or for overlapping host names in the case of wildcard routes. Please be aware that if namespace ownership checks are disabled, routes in a different namespace can use this mechanism to 'steal' sub\-paths for existing domains. This is only safe if route creation privileges are restricted, or if all the users can be trusted.
7373

74+
.PP
75+
\fB\-\-enable\-ingress\fP=false
76+
Enable configuration via ingress resources
77+
7478
.PP
7579
\fB\-\-f5\-host\fP=""
7680
The host of F5 BIG\-IP's management interface

docs/man/man1/openshift-infra-router.1

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ You may restrict the set of routes exposed to a single project (with \-\-namespa
9393
\fB\-\-disable\-namespace\-ownership\-check\fP=false
9494
Disables the namespace ownership checks for a route host with different paths or for overlapping host names in the case of wildcard routes. Please be aware that if namespace ownership checks are disabled, routes in a different namespace can use this mechanism to 'steal' sub\-paths for existing domains. This is only safe if route creation privileges are restricted, or if all the users can be trusted.
9595

96+
.PP
97+
\fB\-\-enable\-ingress\fP=false
98+
Enable configuration via ingress resources
99+
96100
.PP
97101
\fB\-\-extended\-validation\fP=true
98102
If set, then an additional extended validation step is performed on all routes admitted in by this router. Defaults to true and enables the extended validation checks.

pkg/api/helpers.go

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package api
33
import (
44
"fmt"
55

6+
kapi "k8s.io/kubernetes/pkg/api"
67
"k8s.io/kubernetes/pkg/api/validation"
78
"k8s.io/kubernetes/pkg/api/validation/path"
89
)
@@ -33,3 +34,10 @@ func GetFieldLabelConversionFunc(supportedLabels map[string]string, overrideLabe
3334
return "", "", fmt.Errorf("field label not supported: %s", label)
3435
}
3536
}
37+
38+
// GetResourceKey returns a string of the form [namespace]/[name] for
39+
// the given resource. This is a common way of ensuring a key for a
40+
// resource that is unique across the cluster.
41+
func GetResourceKey(obj kapi.ObjectMeta) string {
42+
return fmt.Sprintf("%s/%s", obj.Namespace, obj.Name)
43+
}

pkg/cmd/infra/router/f5.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func (o *F5RouterOptions) Run() error {
225225

226226
factory := o.RouterSelection.NewFactory(oc, kc)
227227
watchNodes := (len(o.InternalAddress) != 0 && len(o.VxlanGateway) != 0)
228-
controller := factory.Create(plugin, watchNodes)
228+
controller := factory.Create(plugin, watchNodes, o.EnableIngress)
229229
controller.Run()
230230

231231
select {}

pkg/cmd/infra/router/router.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ type RouterSelection struct {
5454
AllowWildcardRoutes bool
5555

5656
DisableNamespaceOwnershipCheck bool
57+
58+
EnableIngress bool
5759
}
5860

5961
// Bind sets the appropriate labels
@@ -70,6 +72,7 @@ func (o *RouterSelection) Bind(flag *pflag.FlagSet) {
7072
flag.StringSliceVar(&o.AllowedDomains, "allowed-domains", envVarAsStrings("ROUTER_ALLOWED_DOMAINS", "", ","), "List of comma separated domains to allow in routes. If specified, only the domains in this list will be allowed routes. Note that domains in the denied list take precedence over the ones in the allowed list")
7173
flag.BoolVar(&o.AllowWildcardRoutes, "allow-wildcard-routes", cmdutil.Env("ROUTER_ALLOW_WILDCARD_ROUTES", "") == "true", "Allow wildcard host names for routes")
7274
flag.BoolVar(&o.DisableNamespaceOwnershipCheck, "disable-namespace-ownership-check", cmdutil.Env("ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK", "") == "true", "Disables the namespace ownership checks for a route host with different paths or for overlapping host names in the case of wildcard routes. Please be aware that if namespace ownership checks are disabled, routes in a different namespace can use this mechanism to 'steal' sub-paths for existing domains. This is only safe if route creation privileges are restricted, or if all the users can be trusted.")
75+
flag.BoolVar(&o.EnableIngress, "enable-ingress", cmdutil.Env("ROUTER_ENABLE_INGRESS", "") == "true", "Enable configuration via ingress resources")
7376
}
7477

7578
// RouteSelectionFunc returns a func that identifies the host for a route.
@@ -81,10 +84,14 @@ func (o *RouterSelection) RouteSelectionFunc() controller.RouteHostFunc {
8184
if !o.OverrideHostname && len(route.Spec.Host) > 0 {
8285
return route.Spec.Host
8386
}
87+
// GetNameForHost returns the ingress name for a generated route, and the route route
88+
// name otherwise. When a route and ingress in the same namespace share a name, the
89+
// route and the ingress' rules should receive the same generated host.
90+
nameForHost := controller.GetNameForHost(route.Name)
8491
s, err := variable.ExpandStrict(o.HostnameTemplate, func(key string) (string, bool) {
8592
switch key {
8693
case "name":
87-
return route.Name, true
94+
return nameForHost, true
8895
case "namespace":
8996
return route.Namespace, true
9097
default:

pkg/cmd/infra/router/template.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ func (o *TemplateRouterOptions) Run() error {
215215
plugin := controller.NewHostAdmitter(uniqueHostPlugin, o.RouteAdmissionFunc(), o.AllowWildcardRoutes, o.RouterSelection.DisableNamespaceOwnershipCheck, controller.RejectionRecorder(statusPlugin))
216216

217217
factory := o.RouterSelection.NewFactory(oc, kc)
218-
controller := factory.Create(plugin, false)
218+
controller := factory.Create(plugin, false, o.EnableIngress)
219219
controller.Run()
220220

221221
proc.StartReaper()

pkg/route/api/v1/defaults.go

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package v1
22

33
import "k8s.io/kubernetes/pkg/runtime"
44

5+
// If adding or changing route defaults, updates may be required to
6+
// pkg/router/controller/controller.go to ensure the routes generated from
7+
// ingress resources will match routes created via the api.
8+
59
func SetDefaults_RouteSpec(obj *RouteSpec) {
610
if len(obj.WildcardPolicy) == 0 {
711
obj.WildcardPolicy = WildcardPolicyNone

pkg/router/controller/controller.go

+116-14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/golang/glog"
99
kapi "k8s.io/kubernetes/pkg/api"
10+
"k8s.io/kubernetes/pkg/apis/extensions"
1011
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
1112
"k8s.io/kubernetes/pkg/util/sets"
1213
utilwait "k8s.io/kubernetes/pkg/util/wait"
@@ -30,25 +31,38 @@ type RouterController struct {
3031
NextRoute func() (watch.EventType, *routeapi.Route, error)
3132
NextNode func() (watch.EventType, *kapi.Node, error)
3233
NextEndpoints func() (watch.EventType, *kapi.Endpoints, error)
34+
NextIngress func() (watch.EventType, *extensions.Ingress, error)
35+
NextSecret func() (watch.EventType, *kapi.Secret, error)
3336

3437
RoutesListConsumed func() bool
3538
EndpointsListConsumed func() bool
39+
IngressesListConsumed func() bool
40+
SecretsListConsumed func() bool
3641
routesListConsumed bool
3742
endpointsListConsumed bool
43+
ingressesListConsumed bool
44+
secretsListConsumed bool
3845
filteredByNamespace bool
3946
syncing bool
4047

4148
RoutesListSuccessfulAtLeastOnce func() bool
4249
EndpointsListSuccessfulAtLeastOnce func() bool
50+
IngressesListSuccessfulAtLeastOnce func() bool
51+
SecretsListSuccessfulAtLeastOnce func() bool
4352
RoutesListCount func() int
4453
EndpointsListCount func() int
54+
IngressesListCount func() int
55+
SecretsListCount func() int
4556

4657
WatchNodes bool
4758

4859
Namespaces NamespaceLister
4960
NamespaceSyncInterval time.Duration
5061
NamespaceWaitInterval time.Duration
5162
NamespaceRetries int
63+
64+
EnableIngress bool
65+
IngressTranslator *IngressTranslator
5266
}
5367

5468
// Run begins watching and syncing.
@@ -63,6 +77,10 @@ func (c *RouterController) Run() {
6377
if c.WatchNodes {
6478
go utilwait.Forever(c.HandleNode, 0)
6579
}
80+
if c.EnableIngress {
81+
go utilwait.Forever(c.HandleIngress, 0)
82+
go utilwait.Forever(c.HandleSecret, 0)
83+
}
6684
go c.watchForFirstSync()
6785
}
6886

@@ -74,22 +92,31 @@ func (c *RouterController) handleFirstSync() bool {
7492

7593
synced := c.RoutesListSuccessfulAtLeastOnce() &&
7694
c.EndpointsListSuccessfulAtLeastOnce() &&
77-
(c.Namespaces == nil || c.filteredByNamespace)
95+
(c.Namespaces == nil || c.filteredByNamespace) &&
96+
(!c.EnableIngress ||
97+
(c.IngressesListSuccessfulAtLeastOnce() && c.SecretsListSuccessfulAtLeastOnce()))
7898
if !synced {
7999
return false
80100
}
81101

82-
// If either of the event queues were empty after the initial
83-
// List, the tracking listConsumed variable's default value of
84-
// 'false' may prevent the router from committing the readiness
85-
// status. Set the value to 'true' to ensure that state will be
86-
// committed if necessary.
102+
// If any of the event queues were empty after the initial List,
103+
// the tracking listConsumed variable's default value of 'false'
104+
// may prevent the router from committing. Set the value to
105+
// 'true' to ensure that state can be committed if necessary.
87106
if c.RoutesListCount() == 0 {
88107
c.routesListConsumed = true
89108
}
90109
if c.EndpointsListCount() == 0 {
91110
c.endpointsListConsumed = true
92111
}
112+
if c.EnableIngress {
113+
if c.IngressesListCount() == 0 {
114+
c.ingressesListConsumed = true
115+
}
116+
if c.SecretsListCount() == 0 {
117+
c.secretsListConsumed = true
118+
}
119+
}
93120
c.commit()
94121

95122
return true
@@ -109,6 +136,14 @@ func (c *RouterController) HandleNamespaces() {
109136
for i := 0; i < c.NamespaceRetries; i++ {
110137
namespaces, err := c.Namespaces.NamespaceNames()
111138
if err == nil {
139+
140+
// The ingress translator synchronizes access to its cache with a
141+
// lock, so calls to it are made outside of the controller lock to
142+
// avoid unintended interaction.
143+
if c.EnableIngress {
144+
c.IngressTranslator.UpdateNamespaces(namespaces)
145+
}
146+
112147
c.lock.Lock()
113148
defer c.lock.Unlock()
114149

@@ -161,13 +196,7 @@ func (c *RouterController) HandleRoute() {
161196
c.lock.Lock()
162197
defer c.lock.Unlock()
163198

164-
glog.V(4).Infof("Processing Route: %s -> %s", route.Name, route.Spec.To.Name)
165-
glog.V(4).Infof(" Alias: %s", route.Spec.Host)
166-
glog.V(4).Infof(" Event: %s", eventType)
167-
168-
if err := c.Plugin.HandleRoute(eventType, route); err != nil {
169-
utilruntime.HandleError(err)
170-
}
199+
c.processRoute(eventType, route)
171200

172201
// Change the local sync state within the lock to ensure that all
173202
// event handlers have the same view of sync state.
@@ -196,10 +225,61 @@ func (c *RouterController) HandleEndpoints() {
196225
c.commit()
197226
}
198227

228+
// HandleIngress handles a single Ingress event and synchronizes the router backend.
229+
func (c *RouterController) HandleIngress() {
230+
eventType, ingress, err := c.NextIngress()
231+
if err != nil {
232+
utilruntime.HandleError(fmt.Errorf("unable to read ingress: %v", err))
233+
return
234+
}
235+
236+
// The ingress translator synchronizes access to its cache with a
237+
// lock, so calls to it are made outside of the controller lock to
238+
// avoid unintended interaction.
239+
events := c.IngressTranslator.TranslateIngressEvent(eventType, ingress)
240+
241+
c.lock.Lock()
242+
defer c.lock.Unlock()
243+
244+
c.processIngressEvents(events)
245+
246+
// Change the local sync state within the lock to ensure that all
247+
// event handlers have the same view of sync state.
248+
c.ingressesListConsumed = c.IngressesListConsumed()
249+
c.commit()
250+
}
251+
252+
// HandleSecret handles a single Secret event and synchronizes the router backend.
253+
func (c *RouterController) HandleSecret() {
254+
eventType, secret, err := c.NextSecret()
255+
if err != nil {
256+
utilruntime.HandleError(fmt.Errorf("unable to read secret: %v", err))
257+
return
258+
259+
}
260+
261+
// The ingress translator synchronizes access to its cache with a
262+
// lock, so calls to it are made outside of the controller lock to
263+
// avoid unintended interaction.
264+
events := c.IngressTranslator.TranslateSecretEvent(eventType, secret)
265+
266+
c.lock.Lock()
267+
defer c.lock.Unlock()
268+
269+
c.processIngressEvents(events)
270+
271+
// Change the local sync state within the lock to ensure that all
272+
// event handlers have the same view of sync state.
273+
c.secretsListConsumed = c.SecretsListConsumed()
274+
c.commit()
275+
}
276+
199277
// commit notifies the plugin that it is safe to commit state.
200278
func (c *RouterController) commit() {
201279
syncing := !(c.endpointsListConsumed && c.routesListConsumed &&
202-
(c.Namespaces == nil || c.filteredByNamespace))
280+
(c.Namespaces == nil || c.filteredByNamespace) &&
281+
(!c.EnableIngress ||
282+
(c.ingressesListConsumed && c.secretsListConsumed)))
203283
c.logSyncState(syncing)
204284
if syncing {
205285
return
@@ -219,3 +299,25 @@ func (c *RouterController) logSyncState(syncing bool) {
219299
}
220300
}
221301
}
302+
303+
// processRoute logs and propagates a route event to the plugin
304+
func (c *RouterController) processRoute(eventType watch.EventType, route *routeapi.Route) {
305+
glog.V(4).Infof("Processing Route: %s/%s -> %s", route.Namespace, route.Name, route.Spec.To.Name)
306+
glog.V(4).Infof(" Alias: %s", route.Spec.Host)
307+
glog.V(4).Infof(" Path: %s", route.Spec.Path)
308+
glog.V(4).Infof(" Event: %s", eventType)
309+
310+
if err := c.Plugin.HandleRoute(eventType, route); err != nil {
311+
utilruntime.HandleError(err)
312+
}
313+
}
314+
315+
// processIngressEvents logs and propagates the route events resulting from an ingress or secret event
316+
func (c *RouterController) processIngressEvents(events []ingressRouteEvents) {
317+
for _, ingressEvent := range events {
318+
glog.V(4).Infof("Processing Ingress %s", ingressEvent.ingressKey)
319+
for _, routeEvent := range ingressEvent.routeEvents {
320+
c.processRoute(routeEvent.eventType, routeEvent.route)
321+
}
322+
}
323+
}

0 commit comments

Comments
 (0)