<p>I want to get the values of the fields declared in the <code>downwardAPI</code> section of a <code>Pod</code>.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Pod
metadata:
  name: sample
  namespace: default
spec:
  containers:
  - image: rpa
    imagePullPolicy: Always
    name: testbot
    volumeMounts:
    - mountPath: /etc/pod-info
      name: pod-info
  volumes:
  - downwardAPI:
      items:
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.labels
        path: labels
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
        path: pod-name
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
        path: pod-namespace
    name: pod-info
</code></pre>
<p>Using <code>client-go</code>, I can use <code>pod.Spec.Volumes[0].DownwardAPI.Items</code> to get the item slice including the <code>fieldPath</code>. But I would now need to dynamically able to fetch whatever values has been declared in the <code>fieldPath</code>. So, from the first item, I would like to access the value of <code>metadata.labels</code>. I could do <code>pod.ObjectMeta.Labels</code> but I would like to access the field dynamically. In terms of Javascript it would have been something like</p>
<pre class="lang-js prettyprint-override"><code>var foo=&quot;metadata.labels&quot;
var fooarr = foo.split(&quot;.&quot;)
var bar={
  metadata:{
    labels: &quot;foobar&quot;
  }
}
var temp = oof
for(lm of lmaoarr){
  temp = temp[lm]
}
console.log(temp)
</code></pre>
<p>How do I do something similar using <code>client-go</code>?</p>

Sayak Mukhopadhyay
<p>The standard kubelet code has logic to <a href="https://github.com/kubernetes/kubernetes/blob/5b1e5387591dd3ad0b3ddacc9e44a6ac7260078e/pkg/kubelet/kubelet_pods.go#L806" rel="nofollow noreferrer">translate the downward API fields into environment variables</a>.  It is neither simple nor generic, though: at the bottom of the stack, only the <a href="https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#capabilities-of-the-downward-api" rel="nofollow noreferrer">specific fields listed in the Kubernetes documentation</a> are supported.  It would be incomplete, but not wrong or inconsistent with standard Kubernetes, to just match on these specific fields:</p>
<pre class="lang-golang prettyprint-override"><code>for _, item := range downwardApiObject.Items {
        switch item.FieldPath.FieldRef {
        case &quot;metadata.name&quot;:
                return pod.ObjectMeta.Name
        }
}
</code></pre>
<p>The actual code:</p>
<ol>
<li>Calls <a href="https://github.com/kubernetes/kubernetes/blob/5b1e5387591dd3ad0b3ddacc9e44a6ac7260078e/pkg/apis/core/pods/helpers.go#L65" rel="nofollow noreferrer"><code>pods.ConvertDownwardAPIFieldLabel</code></a> which does some very lightweight normalization and validation: subscripts are only allowed on <code>metadata.annotations</code> and <code>metadata.labels</code>, only the dozen or so specific field names are allowed, and <code>spec.host</code> is rewritten to <code>spec.nodeName</code>.</li>
<li>Handles the <code>spec.*</code> and <code>status.*</code> variables that depend on non-metadata fields in the pod spec or runtime data.</li>
<li>Delegates to <a href="https://github.com/kubernetes/kubernetes/blob/5b1e5387591dd3ad0b3ddacc9e44a6ac7260078e/pkg/fieldpath/fieldpath.go#L46" rel="nofollow noreferrer"><code>fieldpath.ExtractFieldPathAsString</code></a> which knows how to handle the <code>metadata.*</code> variables.</li>
</ol>
<p>The <a href="https://pkg.go.dev/k8s.io/kubernetes/pkg/fieldpath" rel="nofollow noreferrer"><code>k8s.io/kubernetes/pkg/fieldpath</code></a> package contains a couple of helpers that are used in processing the downward API, and a really short answer to your specific question could be just to call <code>fieldpath.ExtractFieldPathAsString</code> passing it the Pod object, which will handle the metadata fields but nothing else.</p>
