Add a sum function to template evaluation
For example, `{{ sum .Pods "{.items[0:].spec.containers[0:].resources.limits.cpu}"` would return the total number of millicpus for every pod in the supplied list.
@@ -18,10 +18,13 @@ package template
import (
"fmt"
+ "reflect"
"text/template"
"time"
"github.com/Masterminds/sprig"
+ "k8s.io/apimachinery/pkg/api/resource"
+ "k8s.io/client-go/util/jsonpath"
)
// FuncMap returns the functions used for template evaluation
@@ -33,6 +36,7 @@ func FuncMap() template.FuncMap {
extra := template.FuncMap{
"duration": duration,
"percent": percent,
+ "sum": sum,
}
for k, v := range extra {
@@ -54,3 +58,30 @@ func duration(start, completion time.Time) float64 {
func percent(value int64, percent int64) string {
return fmt.Sprintf("%d", int64(float64(value)*(float64(percent)/100.0)))
}
+
+// sum evaluates a JSON path expression against an object and returns the sum of the results coerced to an integral value
+func sum(data interface{}, path string) int64 {
+ var sum int64
+ jp := jsonpath.New("sum")
+ if err := jp.Parse(path); err != nil {
+ return sum
+ }
+ values, err := jp.FindResults(data)
+ if err != nil {
+ return sum
+ }
+ if len(values) == 1 {
+ for i := range values[0] {
+ v := reflect.ValueOf(values[0][i].Interface())
+ if v.Kind() == reflect.Int64 {
+ sum += v.Int()
+ } else if v.CanInterface() {
+ switch vv := v.Interface().(type) {
+ case resource.Quantity:
+ sum += vv.MilliValue()
+ }
+ }
+ }
+ }
+ return sum
+}
