Skip to content

Commit

Permalink
Handle floats
Browse files Browse the repository at this point in the history
  • Loading branch information
Vic Iglesias committed Jan 19, 2017
1 parent ba76d9d commit 077c6f0
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 9 deletions.
10 changes: 10 additions & 0 deletions example/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@
tags:
- operations
- security
- name: redis-port
description: Uses the redis containerPort
kind: Pod
field: .spec.containers[*].ports[*].containerPort
operator: equal
valueType: float64
value: 6379
tags:
- operations
- security
- name: name-regex
description: Includes a name with cd-
kind: Pod
Expand Down
3 changes: 1 addition & 2 deletions pkg/pods/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ func EvaluateRules(config rules.LinterConfig, pods []v1.Pod, tags []string, show
} else {
// Filter active rules by tag
// Currently multiple tags are OR'd
// TODO this is probably sub-optimal in more ways than 1
// Loop taken from: https://www.goinggo.net/2013/11/label-breaks-in-go.html
// label break taken from: https://www.goinggo.net/2013/11/label-breaks-in-go.html
for _, rule := range config {
TagLoop:
for _, ruleTag := range rule.Tags {
Expand Down
67 changes: 60 additions & 7 deletions pkg/rules/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"regexp"
"strconv"
"strings"

"k8s.io/client-go/pkg/util/jsonpath"
)
Expand Down Expand Up @@ -64,20 +65,49 @@ func (kr KubernetesRule) Evaluate(resource []byte) Result {
var out interface{}
var actual string
switch kr.ValueType {
case "float64":
var parsedValue float64
// TODO what should you do if it is not found?
if buf.String() != "" {
floats := strings.Fields(buf.String())
for _, float := range floats {
parsedValue64, err := strconv.ParseFloat(float, 64)
if err != nil {
panic(err)
}
parsedValue = parsedValue64
out, passed = kr.evaluateAsFloat(parsedValue)
if passed {
break
}
}
actual = buf.String()
value = strconv.FormatFloat(kr.Value.(float64), 'f', 4, 64)
}
case "bool":
parsedValue := false
// TODO this is the case where it is unset, what to do?
// TODO what should you do if it is not found?
if buf.String() != "" {
parsedValue, err = strconv.ParseBool(buf.String())
if err != nil {
panic(err)
bools := strings.Fields(buf.String())
for _, boolean := range bools {
parsedValue, err = strconv.ParseBool(boolean)
if err != nil {
panic(err)
}
out, passed = kr.evaluateAsBool(parsedValue)
if passed {
break
}

}
actual = strconv.FormatBool(out.(bool))
value = strconv.FormatBool(kr.Value.(bool))
}
out, passed = kr.evaluateAsBool(parsedValue)
actual = strconv.FormatBool(out.(bool))
value = strconv.FormatBool(kr.Value.(bool))

// String is the default type
default:
// TODO need to figure out what to do with the evaluation of multiple
// fields (ie .spec.containers[*].name )
out, passed = kr.evaluateAsString(buf.String())
actual = out.(string)
if kr.Value != nil {
Expand Down Expand Up @@ -130,6 +160,29 @@ func (kr KubernetesRule) evaluateAsString(value string) (string, bool) {
return value, passed
}

func (kr KubernetesRule) evaluateAsFloat(value float64) (float64, bool) {
var passed bool
switch kr.Operator {
case "null":
passed = true
case "equal":
passed = value == kr.Value.(float64)
case "notequal":
passed = value != kr.Value.(float64)
case "greaterthan":
passed = value > kr.Value.(float64)
case "lessthan":
passed = value < kr.Value.(float64)
case "set":
passed = value != 0
case "unset":
passed = value == 0
default:
panic("Operator not implemented for string type: " + kr.Operator)
}
return value, passed
}

// GetName returns the name of a KubernetesRule
func (kr KubernetesRule) GetName() string {
return kr.Name
Expand Down

0 comments on commit 077c6f0

Please sign in to comment.