Skip to content

Commit 26950a4

Browse files
committed
feat(CustomResourceState): Support quantities
1 parent 3a7e617 commit 26950a4

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

docs/customresourcestate-metrics.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ Supported types are:
254254
* for string the following logic applies
255255
* `"true"` and `"yes"` are mapped to `1.0` and `"false"` and `"no"` are mapped to `0.0` (all case insensitive)
256256
* RFC3339 times are parsed to float timestamp
257+
* Quantities like "250m" or "512Gi" are parsed to float using https://github.com/kubernetes/apimachinery/blob/master/pkg/api/resource/quantity.go
257258
* finally the string is parsed to float using https://pkg.go.dev/strconv#ParseFloat which should support all common number formats. If that fails an error is yielded
258259

259260
##### Example for status conditions on Kubernetes Controllers

pkg/customresourcestate/registry_factory.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"strings"
2626
"time"
2727

28+
"k8s.io/apimachinery/pkg/api/resource"
2829
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2930
"k8s.io/klog/v2"
3031

@@ -690,16 +691,22 @@ func toFloat64(value interface{}, nilIsZero bool) (float64, error) {
690691
}
691692
return 0, nil
692693
case string:
694+
// The string contains a boolean as a string
693695
normalized := strings.ToLower(value.(string))
694696
if normalized == "true" || normalized == "yes" {
695697
return 1, nil
696698
}
697699
if normalized == "false" || normalized == "no" {
698700
return 0, nil
699701
}
702+
// The string contains a RFC3339 timestamp
700703
if t, e := time.Parse(time.RFC3339, value.(string)); e == nil {
701704
return float64(t.Unix()), nil
702705
}
706+
// The string contains a quantity with a suffix like "25m" (milli) or "5Gi" (binarySI)
707+
if t, e := resource.ParseQuantity(value.(string)); e == nil {
708+
return t.AsApproximateFloat64(), nil
709+
}
703710
return strconv.ParseFloat(value.(string), 64)
704711
case byte:
705712
v = float64(vv)

pkg/customresourcestate/registry_factory_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ func init() {
6464
"ready": 4,
6565
},
6666
},
67-
"uptime": 43.21,
67+
"uptime": 43.21,
68+
"quantity_milli": "250m",
69+
"quantity_binarySI": "5Gi",
6870
"condition_values": Array{
6971
Obj{
7072
"name": "a",
@@ -225,6 +227,20 @@ func Test_values(t *testing.T) {
225227
}, wantResult: []eachValue{
226228
newEachValue(t, 1656374400),
227229
}},
230+
{name: "quantity_milli", each: &compiledGauge{
231+
compiledCommon: compiledCommon{
232+
path: mustCompilePath(t, "status", "quantity_milli"),
233+
},
234+
}, wantResult: []eachValue{
235+
newEachValue(t, 0.25),
236+
}},
237+
{name: "quantity_binarySI", each: &compiledGauge{
238+
compiledCommon: compiledCommon{
239+
path: mustCompilePath(t, "status", "quantity_binarySI"),
240+
},
241+
}, wantResult: []eachValue{
242+
newEachValue(t, 5.36870912e+09),
243+
}},
228244
{name: "boolean_string", each: &compiledGauge{
229245
compiledCommon: compiledCommon{
230246
path: mustCompilePath(t, "spec", "paused"),

0 commit comments

Comments
 (0)