Correctly handle zero-weight backends (#70)

Signed-off-by: Alexey Ermakov <alexey.ermakov@zalando.de>
This commit is contained in:
aermakov-zalando
2019-07-30 17:32:36 +02:00
committed by Arjun
parent bd0dd10e72
commit b2194ca136
2 changed files with 32 additions and 20 deletions

View File

@ -3,6 +3,7 @@ package collector
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"strings" "strings"
"time" "time"
@ -81,36 +82,35 @@ func NewSkipperCollector(client kubernetes.Interface, plugin CollectorPlugin, hp
}, nil }, nil
} }
func getAnnotationWeight(backendWeights string, backend string) (float64, bool) { func getAnnotationWeight(backendWeights string, backend string) float64 {
var weightsMap map[string]int var weightsMap map[string]int
err := json.Unmarshal([]byte(backendWeights), &weightsMap) err := json.Unmarshal([]byte(backendWeights), &weightsMap)
if err != nil { if err != nil {
return 0, false return 0
} }
if weight, ok := weightsMap[backend]; ok { if weight, ok := weightsMap[backend]; ok {
return float64(weight) / 100, true return float64(weight) / 100
} }
return 0, false return 0
} }
func getWeights(ingressAnnotations map[string]string, backendAnnotations []string, backend string) float64 { func getWeights(ingressAnnotations map[string]string, backendAnnotations []string, backend string) float64 {
var maxWeight float64 = -1 maxWeight := 0.0
weightSet := false annotationsPresent := false
for _, anno := range backendAnnotations { for _, anno := range backendAnnotations {
if weightsMap, ok := ingressAnnotations[anno]; ok { if weightsMap, ok := ingressAnnotations[anno]; ok {
weight, isPresent := getAnnotationWeight(weightsMap, backend) annotationsPresent = true
if isPresent { maxWeight = math.Max(maxWeight, getAnnotationWeight(weightsMap, backend))
weightSet = true
if weight > maxWeight {
maxWeight = weight
}
}
} }
} }
if weightSet {
return maxWeight // Fallback for ingresses that don't use traffic switching
if !annotationsPresent {
return 1.0
} }
return 1.0
return maxWeight
} }
// getCollector returns a collector for getting the metrics. // getCollector returns a collector for getting the metrics.

View File

@ -177,7 +177,7 @@ func TestSkipperCollector(t *testing.T) {
msg: "test backend is not set", msg: "test backend is not set",
metrics: []int{100, 1500, 700}, metrics: []int{100, 1500, 700},
ingressName: "dummy-ingress", ingressName: "dummy-ingress",
collectedMetric: 1500, collectedMetric: 0,
namespace: "default", namespace: "default",
backend: "backend3", backend: "backend3",
backendWeights: map[string]map[string]int{testBackendWeightsAnnotation: {"backend2": 100, "backend1": 0}}, backendWeights: map[string]map[string]int{testBackendWeightsAnnotation: {"backend2": 100, "backend1": 0}},
@ -185,6 +185,18 @@ func TestSkipperCollector(t *testing.T) {
readyReplicas: 1, readyReplicas: 1,
backendAnnotations: []string{testBackendWeightsAnnotation}, backendAnnotations: []string{testBackendWeightsAnnotation},
}, },
{
msg: "test no annotations set",
metrics: []int{100, 1500, 700},
ingressName: "dummy-ingress",
collectedMetric: 1500,
namespace: "default",
backend: "backend3",
backendWeights: map[string]map[string]int{testBackendWeightsAnnotation: {"backend2": 100, "backend1": 0}},
replicas: 1,
readyReplicas: 1,
backendAnnotations: []string{},
},
{ {
msg: "test partial backend annotations", msg: "test partial backend annotations",
metrics: []int{100, 1500, 700}, metrics: []int{100, 1500, 700},
@ -201,7 +213,7 @@ func TestSkipperCollector(t *testing.T) {
backendAnnotations: []string{testBackendWeightsAnnotation, testStacksetWeightsAnnotation}, backendAnnotations: []string{testBackendWeightsAnnotation, testStacksetWeightsAnnotation},
}, },
} { } {
t.Run(tc.msg, func(tt *testing.T) { t.Run(tc.msg, func(t *testing.T) {
client := fake.NewSimpleClientset() client := fake.NewSimpleClientset()
err := makeIngress(client, tc.namespace, tc.ingressName, tc.backend, tc.backendWeights) err := makeIngress(client, tc.namespace, tc.ingressName, tc.backend, tc.backendWeights)
require.NoError(t, err) require.NoError(t, err)
@ -211,9 +223,9 @@ func TestSkipperCollector(t *testing.T) {
_, err = newDeployment(client, tc.namespace, tc.backend, tc.replicas, tc.readyReplicas) _, err = newDeployment(client, tc.namespace, tc.backend, tc.replicas, tc.readyReplicas)
require.NoError(t, err) require.NoError(t, err)
collector, err := NewSkipperCollector(client, plugin, hpa, config, time.Minute, tc.backendAnnotations, tc.backend) collector, err := NewSkipperCollector(client, plugin, hpa, config, time.Minute, tc.backendAnnotations, tc.backend)
require.NoError(tt, err, "failed to create skipper collector: %v", err) require.NoError(t, err, "failed to create skipper collector: %v", err)
collected, err := collector.GetMetrics() collected, err := collector.GetMetrics()
require.NoError(tt, err, "failed to collect metrics: %v", err) require.NoError(t, err, "failed to collect metrics: %v", err)
require.Len(t, collected, 1, "the number of metrics returned is not 1") require.Len(t, collected, 1, "the number of metrics returned is not 1")
require.EqualValues(t, tc.collectedMetric, collected[0].Custom.Value.Value(), "the returned metric is not expected value") require.EqualValues(t, tc.collectedMetric, collected[0].Custom.Value.Value(), "the returned metric is not expected value")
}) })