diff --git a/README.md b/README.md index e7590f9..4f35903 100644 --- a/README.md +++ b/README.md @@ -200,12 +200,25 @@ func main() { ## Usage -The easiest drop-in way to start using the metrics recorder it with `SetStatusCondition`, which +The easiest drop-in way to start using the metrics recorder is by creating a `SetStatusCondition` wrapper, which comes instead of `meta.SetStatusCondition`. To delete the metrics for a given custom resource, simply call `RemoveConditionsFor` and pass the object. ```go +const ( + kind = "MyCr" +) + +// SetStatusCondition utility function which replaces and wraps meta.SetStatusCondition calls +func (r *MyReconciler) SetStatusCondition(cr *v1.MyCR, condition metav1.Condition) bool { + changed = meta.SetStatusCondition(&cr.Status.Conditions, condition) + if changed { + r.RecordConditionFor(kind, cr, condition.Type, string(condition.Status), condition.Reason) + } + return changed +} + func (r *MyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { // Get the resource we're reconciling cr := new(v1.MyCR) @@ -215,13 +228,13 @@ func (r *MyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re // Remove the metrics when the CR is deleted if cr.DeletionTimeStamp != nil { - r.Recorder.RemoveConditionsFor(cr) + r.Recorder.RemoveConditionsFor(kind, cr) } // ... // Update the status conditions using the recorder (it records the metric if changed) - if r.Recorder.SetStatusCondition(cr, &cr.Status.Conditions, condition) { + if r.SetStatusCondition(cr, condition) { if err = r.Status().Update(ctx, cr); err != nil { return ctrl.Result{}, err } @@ -229,7 +242,4 @@ func (r *MyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re return ctrl.Result{}, nil } -``` - -You can also use `RecordConditionFor` for more flexible metric recording without updating the custom resource's status -conditions, but generally, the `SetStatusCondition` is commonly used in controllers and should be preferred. \ No newline at end of file +``` \ No newline at end of file diff --git a/go.mod b/go.mod index d7549aa..309a41c 100644 --- a/go.mod +++ b/go.mod @@ -6,56 +6,21 @@ require ( github.com/prometheus/client_golang v1.23.2 github.com/prometheus/common v0.66.1 github.com/stretchr/testify v1.11.1 - k8s.io/apimachinery v0.34.1 - sigs.k8s.io/controller-runtime v0.22.1 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect - github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/procfs v0.16.1 // indirect - github.com/x448/float16 v0.8.4 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.9.0 // indirect google.golang.org/protobuf v1.36.8 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.0 // indirect - k8s.io/client-go v0.34.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect - sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/go.sum b/go.sum index b8c728d..d17e73a 100644 --- a/go.sum +++ b/go.sum @@ -3,71 +3,18 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= -github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= @@ -80,105 +27,18 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= -golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE= -k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= -k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc= -k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0= -k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4= -k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo= -k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= -k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.22.1 h1:Ah1T7I+0A7ize291nJZdS1CabF/lB4E++WizgV24Eqg= -sigs.k8s.io/controller-runtime v0.22.1/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= -sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= -sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/pkg/operator_condition_metrics/operator_condition_metrics.go b/pkg/operator_condition_metrics/operator_condition_metrics.go index b3fada6..65bc8de 100644 --- a/pkg/operator_condition_metrics/operator_condition_metrics.go +++ b/pkg/operator_condition_metrics/operator_condition_metrics.go @@ -2,9 +2,6 @@ package operator_condition_metrics import ( metrics "github.com/sourcehawk/go-prometheus-gaugevecset/pkg/gauge_vec_set" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" ) /* @@ -131,6 +128,11 @@ func NewOperatorConditionsGauge(metricNamespace string) *OperatorConditionsGauge } } +type ObjectLike interface { + GetName() string + GetNamespace() string +} + // ConditionMetricRecorder records metrics for Kubernetes style `metav1.Condition` // objects on custom resources, using a Prometheus gauge. // @@ -185,59 +187,20 @@ type ConditionMetricRecorder struct { // Reason: "KeyAuthorizationError", // }) func (r *ConditionMetricRecorder) RecordConditionFor( - object client.Object, condition metav1.Condition, + kind string, object ObjectLike, conditionType, conditionStatus, conditionReason string, ) { - kind := object.GetObjectKind().GroupVersionKind().Kind indexValues := []string{r.Controller, kind, object.GetName(), object.GetNamespace()} - groupValues := []string{condition.Type} - extraValues := []string{string(condition.Status), condition.Reason} + groupValues := []string{conditionType} + extraValues := []string{conditionStatus, conditionReason} r.OperatorConditionsGauge.SetGroup(1, indexValues, groupValues, extraValues...) } -// SetStatusCondition sets a condition on the object's status using the Kubernetes -// helper `meta.SetStatusCondition`, and records the corresponding Prometheus metric -// if the condition was changed. -// -// It is a convenience wrapper that ensures metrics and status conditions stay in sync. -// -// Parameters: -// - object: the Kubernetes object (used to extract name, namespace, kind). -// this is the object the condition is tied to in the controller reconciler. -// - conditions: pointer to the object's `.Status.Conditions` slice -// - condition: the metav1.Condition to set -// -// Returns: -// - changed: true if the condition slice was modified -// -// Example: -// -// changed := r.SetStatusCondition( -// obj, -// &obj.Status.Conditions, -// metav1.Condition{ -// Type: "Ready", -// Status: metav1.ConditionTrue, -// Reason: "SuccessfullyReconciled", -// Message: "The resource is ready.", -// }, -// ) -func (r *ConditionMetricRecorder) SetStatusCondition( - object client.Object, conditions *[]metav1.Condition, condition metav1.Condition, -) (changed bool) { - changed = meta.SetStatusCondition(conditions, condition) - if changed { - r.RecordConditionFor(object, condition) - } - return changed -} - // RemoveConditionsFor deletes all condition metrics for a given resource. // This removes all condition types (e.g., Ready, Reconciled) for the resource in one call. // // Typically called when the object is deleted or no longer relevant to the controller (Deletion reconcile). // Returns the number of time series deleted. -func (r *ConditionMetricRecorder) RemoveConditionsFor(object client.Object) (removed int) { - kind := object.GetObjectKind().GroupVersionKind().Kind +func (r *ConditionMetricRecorder) RemoveConditionsFor(kind string, object ObjectLike) (removed int) { return r.OperatorConditionsGauge.DeleteByIndex(r.Controller, kind, object.GetName(), object.GetNamespace()) } diff --git a/pkg/operator_condition_metrics/operator_condition_metrics_benchmark_test.go b/pkg/operator_condition_metrics/operator_condition_metrics_benchmark_test.go index 15aaad1..e64b92c 100644 --- a/pkg/operator_condition_metrics/operator_condition_metrics_benchmark_test.go +++ b/pkg/operator_condition_metrics/operator_condition_metrics_benchmark_test.go @@ -5,10 +5,8 @@ import ( "fmt" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/expfmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - controllermetrics "sigs.k8s.io/controller-runtime/pkg/metrics" ) /* @@ -32,14 +30,33 @@ func generatedName(prefix string, i int) string { return fmt.Sprintf("%s%d", prefix, i) } -func createBenchmarkScenario(tb testing.TB) *ConditionMetricRecorder { +type FakeObject struct { + Name string + Namespace string +} + +func (f *FakeObject) GetName() string { + return f.Name +} + +func (f *FakeObject) GetNamespace() string { + return f.Namespace +} + +type FakeCondition struct { + Type string + Status string + Reason string +} + +func createBenchmarkScenario(tb testing.TB, registry *prometheus.Registry) *ConditionMetricRecorder { tb.Helper() ns := "bench_ns_" + generatedName("", tb.(*testing.B).N) gauge := NewOperatorConditionsGauge(ns) - _ = controllermetrics.Registry.Register(gauge) + _ = registry.Register(gauge) tb.Cleanup(func() { - controllermetrics.Registry.Unregister(gauge) + registry.Unregister(gauge) }) rec := &ConditionMetricRecorder{ @@ -47,30 +64,25 @@ func createBenchmarkScenario(tb testing.TB) *ConditionMetricRecorder { OperatorConditionsGauge: gauge, } - obj := &metav1.PartialObjectMetadata{} - gvk := schema.GroupVersionKind{ - Group: "benchmark.io", - Version: "v1", - Kind: "Benchmark", - } - condition := metav1.Condition{ - Status: metav1.ConditionTrue, // doesn't matter, cardinality controlled by reason + obj := &FakeObject{} + + condition := &FakeCondition{ + Status: "True", // doesn't matter, cardinality decided by Reason } for i := 0; i < controllerCount; i++ { - gvk.Kind = generatedName("Controller", i) - obj.SetGroupVersionKind(gvk) + kind := generatedName("Controller", i) for j := 0; j < resourcesPerController; j++ { - obj.SetName(generatedName("Resource", j)) - obj.SetNamespace(generatedName("namespace", j)) + obj.Name = generatedName("Resource", j) + obj.Namespace = generatedName("namespace", j) for k := 0; k < conditionsPerController; k++ { condition.Type = generatedName("condition", k) for v := 0; v < variantsPerCondition; v++ { condition.Reason = generatedName("variant", v) - rec.RecordConditionFor(obj, condition) + rec.RecordConditionFor(kind, obj, condition.Type, condition.Reason, condition.Reason) } } } @@ -85,21 +97,27 @@ func createBenchmarkScenario(tb testing.TB) *ConditionMetricRecorder { // // Reports: ns/op for each sub-benchmark. func Benchmark_ConditionMetricsRecorder_TimePerCall(b *testing.B) { - rec := createBenchmarkScenario(b) + reg := prometheus.NewRegistry() + rec := createBenchmarkScenario(b, reg) // Use a stable object that exists in the populated dataset. - obj := &metav1.PartialObjectMetadata{} - obj.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "benchmark.io", - Version: "v1", - Kind: "Controller0", - }) - obj.SetName("Resource0") - obj.SetNamespace("namespace0") + kind := "Benchmark" + obj := &FakeObject{ + Name: "Resource0", + Namespace: "namespace0", + } // Two variants in the same (controller,kind,name,namespace,condition) group. - condTrue := metav1.Condition{Type: "condition0", Status: metav1.ConditionTrue, Reason: "variant0"} - condFalse := metav1.Condition{Type: "condition0", Status: metav1.ConditionFalse, Reason: "variant1"} + condTrue := &FakeCondition{ + Type: "condition0", + Status: "True", + Reason: "variant0", + } + condFalse := &FakeCondition{ + Type: "condition0", + Status: "False", + Reason: "variant0", + } b.Run("RecordConditionFor", func(b *testing.B) { b.ReportAllocs() @@ -108,9 +126,9 @@ func Benchmark_ConditionMetricsRecorder_TimePerCall(b *testing.B) { for i := 0; i < b.N; i++ { // Flip between two variants if (i & 1) == 0 { - rec.RecordConditionFor(obj, condTrue) + rec.RecordConditionFor(kind, obj, condTrue.Type, condTrue.Status, condTrue.Reason) } else { - rec.RecordConditionFor(obj, condFalse) + rec.RecordConditionFor(kind, obj, condFalse.Type, condFalse.Status, condFalse.Reason) } } }) @@ -122,10 +140,10 @@ func Benchmark_ConditionMetricsRecorder_TimePerCall(b *testing.B) { for i := 0; i < b.N; i++ { // Ensure there is something to remove, but do not count the set time. b.StopTimer() - rec.RecordConditionFor(obj, condTrue) + rec.RecordConditionFor(kind, obj, condTrue.Type, condTrue.Status, condTrue.Reason) b.StartTimer() - rec.RemoveConditionsFor(obj) + rec.RemoveConditionsFor(kind, obj) } }) } @@ -134,13 +152,14 @@ func Benchmark_ConditionMetricsRecorder_TimePerCall(b *testing.B) { // // Reports: Metric size in KB retrieved from the registry. func Benchmark_ConditionMetricsRecorder_PrometheusMemorySize(b *testing.B) { - _ = createBenchmarkScenario(b) + reg := prometheus.NewRegistry() + _ = createBenchmarkScenario(b, reg) b.ReportAllocs() b.ResetTimer() b.ReportMetric(float64(maxCardinality), "series/op") - mfs, err := controllermetrics.Registry.Gather() + mfs, err := reg.Gather() if err != nil { b.Fatalf("gather: %v", err) } diff --git a/pkg/operator_condition_metrics/operator_condition_metrics_test.go b/pkg/operator_condition_metrics/operator_condition_metrics_test.go index 4d9f0df..23cf2c5 100644 --- a/pkg/operator_condition_metrics/operator_condition_metrics_test.go +++ b/pkg/operator_condition_metrics/operator_condition_metrics_test.go @@ -4,33 +4,25 @@ import ( "strings" "testing" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - controllermetrics "sigs.k8s.io/controller-runtime/pkg/metrics" ) // helper: make a minimal client.Object with Kind/Name/Namespace set. // metav1.PartialObjectMetadata satisfies client.Object and lets us set GVK. -func makeObj(kind, name, namespace string) *metav1.PartialObjectMetadata { - obj := &metav1.PartialObjectMetadata{ - TypeMeta: metav1.TypeMeta{ - Kind: kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, +func makeObj(name, namespace string) *FakeObject { + return &FakeObject{ + Name: name, + Namespace: namespace, } - // Set Kind explicitly (GetObjectKind().GroupVersionKind().Kind reads this) - obj.GetObjectKind().SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind(kind)) - return obj } func TestConditionMetricRecorder_Record_Transition_And_SecondCondition(t *testing.T) { gauge := NewOperatorConditionsGauge("test_record_transition_and_second_condition") - _ = controllermetrics.Registry.Register(gauge) + reg := prometheus.NewRegistry() + _ = reg.Register(gauge) // Arrange rec := &ConditionMetricRecorder{ @@ -40,28 +32,16 @@ func TestConditionMetricRecorder_Record_Transition_And_SecondCondition(t *testin kind := "MyCRD" name := "cr-1" ns := "prod" - obj := makeObj(kind, name, ns) + obj := makeObj(name, ns) // Record Ready=True - rec.RecordConditionFor(obj, metav1.Condition{ - Type: "Ready", - Status: metav1.ConditionTrue, - Reason: "", - }) + rec.RecordConditionFor(kind, obj, "Ready", "True", "") // Flip Ready -> False with reason - rec.RecordConditionFor(obj, metav1.Condition{ - Type: "Ready", - Status: metav1.ConditionFalse, - Reason: "Failed", - }) + rec.RecordConditionFor(kind, obj, "Ready", "False", "Failed") // Another condition Synchronized=True (independent group) - rec.RecordConditionFor(obj, metav1.Condition{ - Type: "Synchronized", - Status: metav1.ConditionTrue, - Reason: "", - }) + rec.RecordConditionFor(kind, obj, "Synchronized", "True", "") // Expect: Ready False(reason)=1, Synchronized True=1 want := ` @@ -72,19 +52,20 @@ test_record_transition_and_second_condition_controller_condition{condition="Sync ` require.NoError(t, testutil.GatherAndCompare( - controllermetrics.Registry, + reg, strings.NewReader(want), "test_record_transition_and_second_condition_controller_condition", ), ) - removed := rec.RemoveConditionsFor(obj) + removed := rec.RemoveConditionsFor(kind, obj) assert.Equal(t, 2, removed) } func TestConditionMetricRecorder_RemoveConditionsFor(t *testing.T) { gauge := NewOperatorConditionsGauge("test_remove_conditions_for_condition") - _ = controllermetrics.Registry.Register(gauge) + reg := prometheus.NewRegistry() + _ = reg.Register(gauge) // Arrange rec := &ConditionMetricRecorder{ Controller: "my-controller", @@ -93,26 +74,19 @@ func TestConditionMetricRecorder_RemoveConditionsFor(t *testing.T) { kind := "MyCRD" name := "cr-2" ns := "staging" - obj := makeObj(kind, name, ns) - - rec.RecordConditionFor(obj, metav1.Condition{ - Type: "Ready", - Status: metav1.ConditionTrue, - }) - rec.RecordConditionFor(obj, metav1.Condition{ - Type: "Synchronized", - Status: metav1.ConditionFalse, - Reason: "SyncPending", - }) + obj := makeObj(name, ns) + + rec.RecordConditionFor(kind, obj, "Ready", "True", "") + rec.RecordConditionFor(kind, obj, "Synchronized", "False", "SyncPending") // Remove all condition series for this object - removed := rec.RemoveConditionsFor(obj) + removed := rec.RemoveConditionsFor(kind, obj) assert.Equal(t, 2, removed) // No series remain for this object require.NoError(t, testutil.GatherAndCompare( - controllermetrics.Registry, + reg, strings.NewReader(""), "test_remove_conditions_for_condition_controller_condition", ), @@ -121,7 +95,8 @@ func TestConditionMetricRecorder_RemoveConditionsFor(t *testing.T) { func TestConditionMetricRecorder_SetsKindLabelFromObject(t *testing.T) { gauge := NewOperatorConditionsGauge("test_sets_kind_label_from_object") - _ = controllermetrics.Registry.Register(gauge) + reg := prometheus.NewRegistry() + _ = reg.Register(gauge) ctrl := "my-controller" rec := &ConditionMetricRecorder{ Controller: ctrl, @@ -130,13 +105,10 @@ func TestConditionMetricRecorder_SetsKindLabelFromObject(t *testing.T) { kind := "FancyKind" name := "obj-1" ns := "ns-1" - obj := makeObj(kind, name, ns) + obj := makeObj(name, ns) // Record a condition - rec.RecordConditionFor(obj, metav1.Condition{ - Type: "Ready", - Status: metav1.ConditionTrue, - }) + rec.RecordConditionFor(kind, obj, "Ready", "True", "") // Expect the 'kind' label to reflect the object's Kind want := ` @@ -146,7 +118,7 @@ test_sets_kind_label_from_object_controller_condition{condition="Ready",controll ` require.NoError(t, testutil.GatherAndCompare( - controllermetrics.Registry, + reg, strings.NewReader(want), "test_sets_kind_label_from_object_controller_condition", ),