Skip to content

Commit

Permalink
cmd/contour: Add flag to specify status.loadbalancer address statically
Browse files Browse the repository at this point in the history
Adds the `--ingress-status-address` flag to specify what address should be added to Ingress `status.loadbalancer` stanza by Contour.

Setting this flag will disable the automatic Envoy service watching for those details.

Fixes projectcontour#2387
Updates projectcontour#403

Further documentation to come under projectcontour#403.

Signed-off-by: Nick Young <ynick@vmware.com>
  • Loading branch information
Nick Young committed Apr 17, 2020
1 parent 877add2 commit 63a1f7c
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 8 deletions.
24 changes: 24 additions & 0 deletions cmd/contour/ingressstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package main

import (
"net"
"sync"

"github.com/projectcontour/contour/internal/k8s"
Expand Down Expand Up @@ -97,3 +98,26 @@ func (isw *loadBalancerStatusWriter) Start(stop <-chan struct{}) error {
}
}
}

func parseStatusFlag(status string) v1.LoadBalancerStatus {

// Use the parseability by net.ParseIP as a signal, since we need
// to pass a string into the v1.LoadBalancerIngress anyway.
if ip := net.ParseIP(status); ip != nil {
return v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
IP: status,
},
},
}
}

return v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: status,
},
},
}
}
105 changes: 105 additions & 0 deletions cmd/contour/ingressstatus_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// 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 main

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/projectcontour/contour/internal/k8s"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
)

func Test_loadBalancerStatusWriter_Start(t *testing.T) {
type fields struct {
log logrus.FieldLogger
clients *k8s.Clients
isLeader chan struct{}
lbStatus chan v1.LoadBalancerStatus
}
type args struct {
stop <-chan struct{}
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
isw := &loadBalancerStatusWriter{
log: tt.fields.log,
clients: tt.fields.clients,
isLeader: tt.fields.isLeader,
lbStatus: tt.fields.lbStatus,
}
if err := isw.Start(tt.args.stop); (err != nil) != tt.wantErr {
t.Errorf("loadBalancerStatusWriter.Start() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func Test_parseStatusFlag(t *testing.T) {
tests := []struct {
name string
status string
want v1.LoadBalancerStatus
}{
{
name: "IPv4",
status: "10.0.0.1",
want: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
IP: "10.0.0.1",
},
},
},
},
{
name: "IPv6",
status: "2001:4860:4860::8888",
want: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
IP: "2001:4860:4860::8888",
},
},
},
},
{
name: "arbitrary string",
status: "anarbitrarystring",
want: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: "anarbitrarystring",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if diff := cmp.Diff(parseStatusFlag(tt.status), tt.want); diff != "" {
t.Errorf("parseStatusFlag failed: %s", diff)
}
})
}
}
22 changes: 14 additions & 8 deletions cmd/contour/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ 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("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)
Expand Down Expand Up @@ -303,14 +303,20 @@ func doServe(log logrus.FieldLogger, ctx *serveContext) error {
}
g.Add(lbsw.Start)

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

} else {
log.Infof("setting Ingress status to %q, disabling watching %q service", ctx.ingressStatusAddress, ctx.envoyServiceName)
lbsw.lbStatus <- parseStatusFlag(ctx.ingressStatusAddress)
}
factory := clients.NewInformerFactoryForNamespace(ctx.envoyServiceNamespace)
factory.Core().V1().Services().Informer().AddEventHandler(ssw)
g.Add(startInformer(factory, log.WithField("context", "serviceStatusLoadBalancerWatcher")))

g.Add(func(stop <-chan struct{}) error {
log := log.WithField("context", "grpc")
Expand Down
3 changes: 3 additions & 0 deletions cmd/contour/servecontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ type serveContext struct {
// ingress class
ingressClass string

// Address to be placed in status.loadbalancer field of Ingress objects.
ingressStatusAddress string

// envoy's stats listener parameters
statsAddr string
statsPort int
Expand Down

0 comments on commit 63a1f7c

Please sign in to comment.