From 0c178252b2aa4d845c48f5e44cc29a89462d622d Mon Sep 17 00:00:00 2001 From: Fernando Diaz Date: Fri, 22 Sep 2017 17:21:32 -0500 Subject: [PATCH] Correct Error Handling to avoid panics and add more logging to template When a type error is found we return an empty object of the expected type(Example: return "" for string return type). Also makes adds logging to all errors caused by type and corrects all related logging for consistency. --- controllers/nginx/pkg/template/template.go | 58 +++++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/controllers/nginx/pkg/template/template.go b/controllers/nginx/pkg/template/template.go index b3762586e8..943c436312 100644 --- a/controllers/nginx/pkg/template/template.go +++ b/controllers/nginx/pkg/template/template.go @@ -171,9 +171,14 @@ func formatIP(input string) string { } // buildResolvers returns the resolvers reading the /etc/resolv.conf file -func buildResolvers(a interface{}) string { +func buildResolvers(input interface{}) string { // NGINX need IPV6 addresses to be surrounded by brackets - nss := a.([]net.IP) + nss, ok := input.([]net.IP) + if !ok { + glog.Errorf("expected a '[]net.IP' type but %T was returned", input) + return "" + } + if len(nss) == 0 { return "" } @@ -196,6 +201,7 @@ func buildResolvers(a interface{}) string { func buildLocation(input interface{}) string { location, ok := input.(*ingress.Location) if !ok { + glog.Errorf("expected an '*ingress.Location' type but %T was returned", input) return slash } @@ -220,6 +226,7 @@ func buildLocation(input interface{}) string { func buildAuthLocation(input interface{}) string { location, ok := input.(*ingress.Location) if !ok { + glog.Errorf("expected an '*ingress.Location' type but %T was returned", input) return "" } @@ -237,6 +244,7 @@ func buildAuthResponseHeaders(input interface{}) []string { location, ok := input.(*ingress.Location) res := []string{} if !ok { + glog.Errorf("expected an '*ingress.Location' type but %T was returned", input) return res } @@ -256,7 +264,8 @@ func buildAuthResponseHeaders(input interface{}) []string { func buildLogFormatUpstream(input interface{}) string { cfg, ok := input.(config.Configuration) if !ok { - glog.Errorf("error an ingress.buildLogFormatUpstream type but %T was returned", input) + glog.Errorf("expected a 'config.Configuration' type but %T was returned", input) + return "" } return cfg.BuildLogFormatUpstream() @@ -267,9 +276,15 @@ func buildLogFormatUpstream(input interface{}) string { // If the annotation ingress.kubernetes.io/add-base-url:"true" is specified it will // add a base tag in the head of the response from the service func buildProxyPass(host string, b interface{}, loc interface{}) string { - backends := b.([]*ingress.Backend) + backends, ok := b.([]*ingress.Backend) + if !ok { + glog.Errorf("expected an '[]*ingress.Backend' type but %T was returned", b) + return "" + } + location, ok := loc.(*ingress.Location) if !ok { + glog.Errorf("expected a '*ingress.Location' type but %T was returned", loc) return "" } @@ -345,6 +360,7 @@ func filterRateLimits(input interface{}) []ratelimit.RateLimit { servers, ok := input.([]*ingress.Server) if !ok { + glog.Errorf("expected a '[]ratelimit.RateLimit' type but %T was returned", input) return ratelimits } for _, server := range servers { @@ -368,6 +384,7 @@ func buildRateLimitZones(input interface{}) []string { servers, ok := input.([]*ingress.Server) if !ok { + glog.Errorf("expected a '[]*ingress.Server' type but %T was returned", input) return zones.List() } @@ -417,6 +434,7 @@ func buildRateLimit(input interface{}) []string { loc, ok := input.(*ingress.Location) if !ok { + glog.Errorf("expected an '*ingress.Location' type but %T was returned", input) return limits } @@ -456,7 +474,7 @@ func buildRateLimit(input interface{}) []string { func isLocationAllowed(input interface{}) bool { loc, ok := input.(*ingress.Location) if !ok { - glog.Errorf("expected an ingress.Location type but %T was returned", input) + glog.Errorf("expected an '*ingress.Location' type but %T was returned", input) return false } @@ -473,7 +491,11 @@ var ( // size of the string to be used as a variable in nginx to avoid // issue with the size of the variable bucket size directive func buildDenyVariable(a interface{}) string { - l := a.(string) + l, ok := a.(string) + if !ok { + glog.Errorf("expected a 'string' type but %T was returned", a) + return "" + } if _, ok := denyPathSlugMap[l]; !ok { denyPathSlugMap[l] = buildRandomUUID() @@ -484,9 +506,16 @@ func buildDenyVariable(a interface{}) string { // TODO: Needs Unit Tests func buildUpstreamName(host string, b interface{}, loc interface{}) string { - backends := b.([]*ingress.Backend) + + backends, ok := b.([]*ingress.Backend) + if !ok { + glog.Errorf("expected an '[]*ingress.Backend' type but %T was returned", b) + return "" + } + location, ok := loc.(*ingress.Location) if !ok { + glog.Errorf("expected a '*ingress.Location' type but %T was returned", loc) return "" } @@ -522,7 +551,8 @@ func isSticky(host string, loc *ingress.Location, stickyLocations map[string][]s func buildNextUpstream(input interface{}) string { nextUpstream, ok := input.(string) if !ok { - glog.Errorf("expected an string type but %T was returned", input) + glog.Errorf("expected a 'string' type but %T was returned", input) + return "" } parts := strings.Split(nextUpstream, " ") @@ -540,7 +570,8 @@ func buildNextUpstream(input interface{}) string { func buildAuthSignURL(input interface{}) string { s, ok := input.(string) if !ok { - glog.Errorf("expected an string type but %T was returned", input) + glog.Errorf("expected an 'string' type but %T was returned", input) + return "" } u, _ := url.Parse(s) @@ -561,7 +592,7 @@ func buildRandomUUID() string { func isValidClientBodyBufferSize(input interface{}) bool { s, ok := input.(string) if !ok { - glog.Errorf("expected an string type but %T was returned", input) + glog.Errorf("expected an 'string' type but %T was returned", input) return false } @@ -602,13 +633,13 @@ type ingressInformation struct { func getIngressInformation(i, p interface{}) *ingressInformation { ing, ok := i.(*extensions.Ingress) if !ok { - glog.V(3).Infof("expected an Ingress type but %T was returned", i) + glog.Errorf("expected an '*extensions.Ingress' type but %T was returned", i) return &ingressInformation{} } path, ok := p.(string) if !ok { - glog.V(3).Infof("expected a string type but %T was returned", p) + glog.Errorf("expected a 'string' type but %T was returned", p) return &ingressInformation{} } @@ -645,7 +676,8 @@ func getIngressInformation(i, p interface{}) *ingressInformation { func buildForwardedFor(input interface{}) string { s, ok := input.(string) if !ok { - glog.Errorf("expected an string type but %T was returned", input) + glog.Errorf("expected a 'string' type but %T was returned", input) + return "" } ffh := strings.Replace(s, "-", "_", -1)