Skip to content

Commit

Permalink
Allow defining valueFrom paths on dynamic paths
Browse files Browse the repository at this point in the history
🎉
  • Loading branch information
rexagod committed Jun 11, 2023
1 parent a14a3cd commit c2362ce
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions pkg/customresourcestate/registry_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,26 @@ type compiledGauge struct {
labelFromKey string
}

func underscoresToIndices(extractedValueFrom string, it interface{}) interface{} {
// `it` is the search space.
_, isResolvable := it.(map[string]interface{})
if !isResolvable {
return nil
}
// `extractedValueFrom` is the search term.
// Split `extractedValueFrom` by underscores.
terms := strings.Split(extractedValueFrom, "_")
resolvedTerm := interface{}(terms[0])
for _, term := range terms[1:] {
t, ok := it.(map[string]interface{})[term]
if !ok {
return resolvedTerm
}
resolvedTerm = t
}
return resolvedTerm
}

func (c *compiledGauge) Values(v interface{}) (result []eachValue, errs []error) {
onError := func(err error) {
errs = append(errs, fmt.Errorf("%s: %v", c.Path(), err))
Expand All @@ -246,8 +266,17 @@ func (c *compiledGauge) Values(v interface{}) (result []eachValue, errs []error)
// "[...]" and not "[]".
len(sValueFrom) > 2 {
extractedValueFrom := sValueFrom[1 : len(sValueFrom)-1]
if key == extractedValueFrom {
gotFloat, err := toFloat64(it, c.NilIsZero)
if strings.HasPrefix(extractedValueFrom, key) {
var gotFloat float64
var err error
if strings.Contains(extractedValueFrom, "_") {
resolvedExtractedValueFrom := underscoresToIndices(extractedValueFrom, it)
if _, didResolveFullPath := resolvedExtractedValueFrom.(string); didResolveFullPath {
gotFloat, err = toFloat64(resolvedExtractedValueFrom, c.NilIsZero)
}
} else {
gotFloat, err = toFloat64(it, c.NilIsZero)
}
if err != nil {
onError(fmt.Errorf("[%s]: %w", key, err))
continue
Expand Down Expand Up @@ -760,10 +789,8 @@ func generate(u *unstructured.Unstructured, f compiledFamily, errLog klog.Verbos
fPaths := resolveWildcard(f.Each.Path(), u.Object)
for _, fPath := range fPaths {
f.Each.SetPath(fPath)
fn()
}
}

if f.Each.LabelFromPath() != nil {
labelsFromPath := make(map[string]valuePath)
flfp := f.Each.LabelFromPath()
Expand All @@ -777,8 +804,8 @@ func generate(u *unstructured.Unstructured, f compiledFamily, errLog klog.Verbos
if len(labelsFromPath) > 0 {
f.Each.SetLabelFromPath(labelsFromPath)
}
fn()
}
fn()

return &metric.Family{
Metrics: metrics,
Expand Down

1 comment on commit c2362ce

@rexagod
Copy link
Owner Author

@rexagod rexagod commented on c2362ce Jun 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: This requires patches kubernetes#2068 and kubernetes#2052 to work and was developed on top of them.


This can be now done like so:

kind: CustomResourceStateMetrics
spec:
  resources:
    - groupVersionKind:
        group: "quota.openshift.io"
        version: "v1"
        kind: "ClusterResourceQuota"
      metrics:
        - name: "openshift_clusterresourcequota_namespace_usage"
          help: "Usage about clusterresource quota per namespace."
          each:
            type: Gauge
            gauge:
              path: [status, namespaces, "*", status]
              labelsFromPath:
                "hard_*": [hard]
                "used_*": [used]
              valueFrom: [used_secrets]
          labelsFromPath:
            "name": [metadata, name]

producing the following metrics,

# HELP kube_customresource_openshift_clusterresourcequota_namespace_usage Usage about clusterresource quota per namespace.
# TYPE kube_customresource_openshift_clusterresourcequota_namespace_usage gauge
kube_customresource_openshift_clusterresourcequota_namespace_usage{customresource_group="quota.openshift.io",customresource_kind="ClusterResourceQuota",customresource_version="v1",hard_pods="10",hard_secrets="20",name="for-user",used_pods="0",used_secrets="6"} 6

for the object,

apiVersion: quota.openshift.io/v1
kind: ClusterResourceQuota
metadata:
  annotations:
    dolor: emet
    lorem: ipsum
  creationTimestamp: '2023-06-11T09:10:58Z'
  generation: 1
  labels:
    baz: que
    foo: bar
  managedFields:
    - apiVersion: quota.openshift.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        'f:spec':
          .: {}
          'f:quota':
            .: {}
            'f:hard':
              .: {}
              'f:pods': {}
              'f:secrets': {}
          'f:selector':
            .: {}
            'f:annotations':
              .: {}
              'f:openshift.io/requester': {}
            'f:labels': {}
      manager: Mozilla
      operation: Update
      time: '2023-06-11T09:10:58Z'
    - apiVersion: quota.openshift.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        'f:metadata':
          'f:annotations':
            .: {}
            'f:dolor': {}
            'f:lorem': {}
          'f:labels':
            .: {}
            'f:baz': {}
            'f:foo': {}
      manager: kubectl-edit
      operation: Update
      time: '2023-06-11T10:26:51Z'
    - apiVersion: quota.openshift.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        'f:status':
          .: {}
          'f:namespaces': {}
          'f:total':
            .: {}
            'f:hard':
              .: {}
              'f:pods': {}
              'f:secrets': {}
            'f:used':
              .: {}
              'f:pods': {}
              'f:secrets': {}
      manager: cluster-policy-controller
      operation: Update
      subresource: status
      time: '2023-06-11T10:31:24Z'
  name: for-user
  resourceVersion: '88273'
  uid: a313b1d5-63f6-4294-83dc-01c38b5d102a
spec:
  quota:
    hard:
      pods: '10'
      secrets: '20'
  selector:
    annotations:
      openshift.io/requester: 'kube:admin'
    labels: null
status:
  namespaces:
    - namespace: foo
      status:
        hard:
          pods: '10'
          secrets: '20'
        used:
          pods: '0'
          secrets: '6'
  total:
    hard:
      pods: '10'
      secrets: '20'
    used:
      pods: '0'
      secrets: '6'
Map expansion error Screenshot 2024-03-11 at 02 46 04

Please sign in to comment.