Skip to content

Commit

Permalink
Document and improve UX of ingress status feature.
Browse files Browse the repository at this point in the history
Fixes projectcontour#403.

Updates the `--ingress-status-address`, `--envoy-service-name`, and `--envoy-service-namespace` flags to be also readable from the config file.

The `serveContext` fields needed to be exported in order for the export to work.

Updated some logging to ensure that you can tell easily which settings are in effect.

Signed-off-by: Nick Young <ynick@vmware.com>
  • Loading branch information
Nick Young committed Apr 24, 2020
1 parent 2205199 commit 43f99e8
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 16 deletions.
16 changes: 15 additions & 1 deletion cmd/contour/ingressstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (isw *loadBalancerStatusWriter) Start(stop <-chan struct{}) error {
}
ingressInformers.Wait()

isw.log.Info("Received a new address for status.loadBalancer")
isw.log.WithField("loadbalancer-address", lbAddress(lbs)).Info("received a new address for status.loadBalancer")

// Create new informer for the new LoadBalancerStatus
factory := isw.clients.NewInformerFactory()
Expand Down Expand Up @@ -121,3 +121,17 @@ func parseStatusFlag(status string) v1.LoadBalancerStatus {
},
}
}

// lbAddress gets the string representation of the first address, for logging.
func lbAddress(lb v1.LoadBalancerStatus) string {

if len(lb.Ingress) == 0 {
return ""
}

if lb.Ingress[0].IP != "" {
return lb.Ingress[0].IP
}

return lb.Ingress[0].Hostname
}
45 changes: 45 additions & 0 deletions cmd/contour/ingressstatus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,48 @@ func Test_parseStatusFlag(t *testing.T) {
})
}
}

func Test_lbAddress(t *testing.T) {
tests := []struct {
name string
lb v1.LoadBalancerStatus
want string
}{
{
name: "empty Loadbalancer",
lb: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{},
},
want: "",
},
{
name: "IP address loadbalancer",
lb: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
IP: "10.0.0.1",
},
},
},
want: "10.0.0.1",
},
{
name: "Hostname loadbalancer",
lb: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: "somedomain.com",
},
},
},
want: "somedomain.com",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if diff := cmp.Diff(lbAddress(tt.lb), tt.want); diff != "" {
t.Errorf("lbAddress failed: %s", diff)
}
})
}
}
17 changes: 9 additions & 8 deletions cmd/contour/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
serve.Flag("root-namespaces", "Restrict contour to searching these namespaces for root ingress routes.").StringVar(&ctx.rootNamespaces)

serve.Flag("ingress-class-name", "Contour IngressClass name.").StringVar(&ctx.ingressClass)
serve.Flag("ingress-status-address", "Address to set in Ingress object status.").StringVar(&ctx.ingressStatusAddress)
serve.Flag("ingress-status-address", "Address to set in Ingress object status.").StringVar(&ctx.IngressStatusAddress)
serve.Flag("envoy-http-access-log", "Envoy HTTP access log.").StringVar(&ctx.httpAccessLog)
serve.Flag("envoy-https-access-log", "Envoy HTTPS access log.").StringVar(&ctx.httpsAccessLog)
serve.Flag("envoy-service-http-address", "Kubernetes Service address for HTTP requests.").StringVar(&ctx.httpAddr)
serve.Flag("envoy-service-https-address", "Kubernetes Service address for HTTPS requests.").StringVar(&ctx.httpsAddr)
serve.Flag("envoy-service-http-port", "Kubernetes Service port for HTTP requests.").IntVar(&ctx.httpPort)
serve.Flag("envoy-service-https-port", "Kubernetes Service port for HTTPS requests.").IntVar(&ctx.httpsPort)
serve.Flag("envoy-service-name", "Envoy Service Name.").StringVar(&ctx.envoyServiceName)
serve.Flag("envoy-service-namespace", "Envoy Service Namespace.").StringVar(&ctx.envoyServiceNamespace)
serve.Flag("envoy-service-name", "Envoy Service Name.").StringVar(&ctx.EnvoyServiceName)
serve.Flag("envoy-service-namespace", "Envoy Service Namespace.").StringVar(&ctx.EnvoyServiceNamespace)
serve.Flag("use-proxy-protocol", "Use PROXY protocol for all listeners.").BoolVar(&ctx.useProxyProto)

serve.Flag("accesslog-format", "Format for Envoy access logs.").StringVar(&ctx.AccessLogFormat)
Expand Down Expand Up @@ -304,18 +304,19 @@ func doServe(log logrus.FieldLogger, ctx *serveContext) error {
g.Add(lbsw.Start)

// step 12. register an informer to watch envoy's service if we haven't been given static details.
if ctx.ingressStatusAddress == "" {
if ctx.IngressStatusAddress == "" {
ssw := &k8s.ServiceStatusLoadBalancerWatcher{
ServiceName: ctx.envoyServiceName,
ServiceName: ctx.EnvoyServiceName,
LBStatus: lbsw.lbStatus,
}
factory := clients.NewInformerFactoryForNamespace(ctx.envoyServiceNamespace)
factory := clients.NewInformerFactoryForNamespace(ctx.EnvoyServiceNamespace)
factory.Core().V1().Services().Informer().AddEventHandler(ssw)
g.Add(startInformer(factory, log.WithField("context", "serviceStatusLoadBalancerWatcher")))
log.WithField("envoy-service-name", ctx.EnvoyServiceName).WithField("envoy-service-namespace", ctx.EnvoyServiceNamespace).Info("Watching Service for Ingress status")

} else {
log.Infof("setting Ingress status to %q, disabling watching %q service", ctx.ingressStatusAddress, ctx.envoyServiceName)
lbsw.lbStatus <- parseStatusFlag(ctx.ingressStatusAddress)
log.WithField("loadbalancer-address", ctx.IngressStatusAddress).Info("Using supplied information for Ingress status")
lbsw.lbStatus <- parseStatusFlag(ctx.IngressStatusAddress)
}

g.Add(func(stop <-chan struct{}) error {
Expand Down
19 changes: 12 additions & 7 deletions cmd/contour/servecontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import (
)

type serveContext struct {
// Note about parameter behavior: if the parameter is going to be in the config file,
// it has to be exported. If not, the YAML decoder will not see the field.

// Enable debug logging
Debug bool

Expand Down Expand Up @@ -63,7 +66,9 @@ type serveContext struct {
ingressClass string

// Address to be placed in status.loadbalancer field of Ingress objects.
ingressStatusAddress string
// May be either a literal IP address or a host name.
// The value will be placed directly into the relevant field inside the status.loadBalancer struct.
IngressStatusAddress string `yaml:"ingress-status-address,omitempty"`

// envoy's stats listener parameters
statsAddr string
Expand Down Expand Up @@ -119,11 +124,11 @@ type serveContext struct {

// envoy service details

// Namespace of the envoy service
envoyServiceNamespace string `yaml:"-"`
// Namespace of the envoy service to inspect for Ingress status details.
EnvoyServiceNamespace string `yaml:"envoy-service-namespace,omitempty"`

// Name of the envoy service
envoyServiceName string `yaml:"-"`
// Name of the envoy service to inspect for Ingress status details.
EnvoyServiceName string `yaml:"envoy-service-name,omitempty"`
}

// newServeContext returns a serveContext initialized to defaults.
Expand Down Expand Up @@ -159,8 +164,8 @@ func newServeContext() *serveContext {
Name: "leader-elect",
},
UseExperimentalServiceAPITypes: false,
envoyServiceName: "envoy",
envoyServiceNamespace: getEnv("CONTOUR_NAMESPACE", "projectcontour"),
EnvoyServiceName: "envoy",
EnvoyServiceNamespace: getEnv("CONTOUR_NAMESPACE", "projectcontour"),
}
}

Expand Down
2 changes: 2 additions & 0 deletions internal/k8s/ingressstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ func (s *IngressStatusUpdater) OnDelete(obj interface{}) {

// ServiceStatusLoadBalancerWatcher implements ResourceEventHandler and
// watches for changes to the status.loadbalancer field
// Note that we specifically *don't* inspect inside the struct, as sending empty values
// is desirable to clear the status.
type ServiceStatusLoadBalancerWatcher struct {
ServiceName string
LBStatus chan v1.LoadBalancerStatus
Expand Down
3 changes: 3 additions & 0 deletions site/docs/master/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Where Contour settings can also be specified with command-line flags, the comman
| accesslog-format | string | `envoy` | This key sets the global [access log format][2] for Envoy. Valid options are `envoy` or `json`. |
| debug | boolean | `false` | Enables debug logging. |
| disablePermitInsecure | boolean | `false` | If this field is true, Contour will ignore `PermitInsecure` field in HTTPProxy documents. |
| envoy-service-name | string | `envoy` | This sets the service name that will be inspected for address details to be applied to Ingress objects. |
| envoy-service-namespace | string | `projectcontour` | This sets the namespace of the service that will be inspected for address details to be applied to Ingress objects. |
| ingress-status-address | string | None | If present, this specifies the address that will be copied into the Ingress status for each Ingress that Contour manages. It is exclusive with `envoy-service-name` and `envoy-service-namespace`.|
| incluster | boolean | `false` | This field specifies that Contour is running in a Kubernetes cluster and should use the in-cluster client access configuration. |
| json-fields | string array | [fields][5]| This is the list the field names to include in the JSON [access log format][2]. |
| kubeconfig | string | `$HOME/.kube/config` | Path to a Kubernetes [kubeconfig file][3] for when Contour is executed outside a cluster. |
Expand Down

0 comments on commit 43f99e8

Please sign in to comment.