Skip to content

Commit

Permalink
refactor DAG and DAG consumers to support >2 Listeners
Browse files Browse the repository at this point in the history
Updates projectcontour#4960.

Signed-off-by: Steve Kriss <krisss@vmware.com>
  • Loading branch information
skriss committed Mar 8, 2023
1 parent 36d6e45 commit 78a040d
Show file tree
Hide file tree
Showing 24 changed files with 608 additions and 653 deletions.
38 changes: 18 additions & 20 deletions cmd/contour/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,22 +335,8 @@ func (s *Server) doServe() error {
}

listenerConfig := xdscache_v3.ListenerConfig{
UseProxyProto: *contourConfiguration.Envoy.Listener.UseProxyProto,
HTTPListeners: map[string]xdscache_v3.Listener{
xdscache_v3.ENVOY_HTTP_LISTENER: {
Name: xdscache_v3.ENVOY_HTTP_LISTENER,
Address: contourConfiguration.Envoy.HTTPListener.Address,
Port: contourConfiguration.Envoy.HTTPListener.Port,
},
},
HTTPAccessLog: contourConfiguration.Envoy.HTTPListener.AccessLog,
HTTPSListeners: map[string]xdscache_v3.Listener{
xdscache_v3.ENVOY_HTTPS_LISTENER: {
Name: xdscache_v3.ENVOY_HTTPS_LISTENER,
Address: contourConfiguration.Envoy.HTTPSListener.Address,
Port: contourConfiguration.Envoy.HTTPSListener.Port,
},
},
UseProxyProto: *contourConfiguration.Envoy.Listener.UseProxyProto,
HTTPAccessLog: contourConfiguration.Envoy.HTTPListener.AccessLog,
HTTPSAccessLog: contourConfiguration.Envoy.HTTPSListener.AccessLog,
AccessLogType: contourConfiguration.Envoy.Logging.AccessLogFormat,
AccessLogJSONFields: contourConfiguration.Envoy.Logging.AccessLogJSONFields,
Expand Down Expand Up @@ -448,6 +434,10 @@ func (s *Server) doServe() error {
connectTimeout: timeouts.ConnectTimeout,
client: s.mgr.GetClient(),
metrics: contourMetrics,
httpAddress: contourConfiguration.Envoy.HTTPListener.Address,
httpPort: contourConfiguration.Envoy.HTTPListener.Port,
httpsAddress: contourConfiguration.Envoy.HTTPSListener.Address,
httpsPort: contourConfiguration.Envoy.HTTPSListener.Port,
})

// Build the core Kubernetes event handler.
Expand Down Expand Up @@ -862,6 +852,10 @@ type dagBuilderConfig struct {
connectTimeout time.Duration
client client.Client
metrics *metrics.Metrics
httpAddress string
httpPort int
httpsAddress string
httpsPort int
}

func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder {
Expand Down Expand Up @@ -914,6 +908,14 @@ func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder {

// Get the appropriate DAG processors.
dagProcessors := []dag.Processor{
// The listener processor has to go first since it
// adds listeners which are roots of the DAG.
&dag.ListenerProcessor{
HTTPAddress: dbc.httpAddress,
HTTPPort: dbc.httpPort,
HTTPSAddress: dbc.httpsAddress,
HTTPSPort: dbc.httpsPort,
},
&dag.IngressProcessor{
EnableExternalNameService: dbc.enableExternalNameService,
FieldLogger: s.log.WithField("context", "IngressProcessor"),
Expand Down Expand Up @@ -949,10 +951,6 @@ func (s *Server) getDAGBuilder(dbc dagBuilderConfig) *dag.Builder {
})
}

// The listener processor has to go last since it looks at
// the output of the other processors.
dagProcessors = append(dagProcessors, &dag.ListenerProcessor{})

var configuredSecretRefs []*types.NamespacedName
if dbc.fallbackCert != nil {
configuredSecretRefs = append(configuredSecretRefs, dbc.fallbackCert)
Expand Down
2 changes: 1 addition & 1 deletion cmd/contour/serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestGetDAGBuilder(t *testing.T) {
// is configured, but we don't currently have test cases that cover
// that so it's OK to keep them in the "common" assertions for now.
assert.Len(t, builder.Processors, 4)
assert.IsType(t, &dag.ListenerProcessor{}, builder.Processors[len(builder.Processors)-1])
assert.IsType(t, &dag.ListenerProcessor{}, builder.Processors[0])
}

t.Run("all default options", func(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/contour/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ func TestHTTPProxyMetrics(t *testing.T) {
FieldLogger: fixture.NewTestLogger(t),
},
Processors: []dag.Processor{
&dag.ListenerProcessor{},
&dag.IngressProcessor{
FieldLogger: fixture.NewTestLogger(t),
},
&dag.HTTPProxyProcessor{},
&dag.ListenerProcessor{},
},
}
for _, o := range tc.objs {
Expand Down
24 changes: 14 additions & 10 deletions internal/dag/accessors.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,14 @@ func externalName(svc *v1.Service) string {
// GetSecureVirtualHost returns the secure virtual host in the DAG that
// matches the provided name, or nil if no matching secure virtual host
// is found.
func (d *DAG) GetSecureVirtualHost(hostname string) *SecureVirtualHost {
return d.SecureVirtualHosts[hostname]
func (d *DAG) GetSecureVirtualHost(listener, hostname string) *SecureVirtualHost {
return d.Listeners[listener].svhostsByName[hostname]
}

// EnsureSecureVirtualHost adds a secure virtual host with the provided
// name to the DAG if it does not already exist, and returns it.
func (d *DAG) EnsureSecureVirtualHost(hostname string) *SecureVirtualHost {
if svh := d.GetSecureVirtualHost(hostname); svh != nil {
func (d *DAG) EnsureSecureVirtualHost(listener, hostname string) *SecureVirtualHost {
if svh := d.GetSecureVirtualHost(listener, hostname); svh != nil {
return svh
}

Expand All @@ -137,27 +137,31 @@ func (d *DAG) EnsureSecureVirtualHost(hostname string) *SecureVirtualHost {
Name: hostname,
},
}
d.SecureVirtualHosts[hostname] = svh

d.Listeners[listener].SecureVirtualHosts = append(d.Listeners[listener].SecureVirtualHosts, svh)
d.Listeners[listener].svhostsByName[svh.Name] = svh
return svh
}

// GetVirtualHost returns the virtual host in the DAG that matches the
// provided name, or nil if no matching virtual host is found.
func (d *DAG) GetVirtualHost(hostname string) *VirtualHost {
return d.VirtualHosts[hostname]
func (d *DAG) GetVirtualHost(listener, hostname string) *VirtualHost {
return d.Listeners[listener].vhostsByName[hostname]
}

// EnsureVirtualHost adds a virtual host with the provided name to the
// DAG if it does not already exist, and returns it.
func (d *DAG) EnsureVirtualHost(hostname string) *VirtualHost {
if vhost := d.GetVirtualHost(hostname); vhost != nil {
func (d *DAG) EnsureVirtualHost(listener, hostname string) *VirtualHost {
if vhost := d.GetVirtualHost(listener, hostname); vhost != nil {
return vhost
}

vhost := &VirtualHost{
Name: hostname,
}
d.VirtualHosts[hostname] = vhost

d.Listeners[listener].VirtualHosts = append(d.Listeners[listener].VirtualHosts, vhost)
d.Listeners[listener].vhostsByName[vhost.Name] = vhost
return vhost
}

Expand Down
47 changes: 44 additions & 3 deletions internal/dag/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package dag

import (
"sort"

"github.com/projectcontour/contour/internal/k8s"
"github.com/projectcontour/contour/internal/metrics"
"github.com/projectcontour/contour/internal/status"
Expand Down Expand Up @@ -65,9 +67,8 @@ func (b *Builder) Build() *DAG {
}

dag := &DAG{
VirtualHosts: map[string]*VirtualHost{},
SecureVirtualHosts: map[string]*SecureVirtualHost{},
StatusCache: status.NewCache(gatewayNSName, gatewayController),
StatusCache: status.NewCache(gatewayNSName, gatewayController),
Listeners: map[string]*Listener{},
}

if b.Metrics != nil {
Expand All @@ -78,5 +79,45 @@ func (b *Builder) Build() *DAG {
for _, p := range b.Processors {
p.Run(dag, &b.Source)
}

// Prune invalid virtual hosts, and Listeners
// without any valid virtual hosts.
listeners := map[string]*Listener{}

for _, listener := range dag.Listeners {
var vhosts []*VirtualHost
for _, vh := range listener.VirtualHosts {
if vh.Valid() {
vhosts = append(vhosts, vh)
}
}
listener.VirtualHosts = vhosts

var svhosts []*SecureVirtualHost
for _, svh := range listener.SecureVirtualHosts {
if svh.Valid() {
svhosts = append(svhosts, svh)
}
}
listener.SecureVirtualHosts = svhosts

if len(listener.VirtualHosts) > 0 || len(listener.SecureVirtualHosts) > 0 {
sort.SliceStable(listener.VirtualHosts, func(i, j int) bool {
return listener.VirtualHosts[i].Name < listener.VirtualHosts[j].Name
})

sort.SliceStable(listener.SecureVirtualHosts, func(i, j int) bool {
return listener.SecureVirtualHosts[i].Name < listener.SecureVirtualHosts[j].Name
})

listener.vhostsByName = nil
listener.svhostsByName = nil

listeners[listener.Name] = listener
}
}

dag.Listeners = listeners

return dag
}
Loading

0 comments on commit 78a040d

Please sign in to comment.