I want to get the values of the fields declared in the downwardAPI section of a Pod.
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-infoUsing client-go, I can use pod.Spec.Volumes[0].DownwardAPI.Items to get the item slice including the fieldPath. But I would now need to dynamically able to fetch whatever values has been declared in the fieldPath. So, from the first item, I would like to access the value of metadata.labels. I could do pod.ObjectMeta.Labels but I would like to access the field dynamically. In terms of Javascript it would have been something like
var foo="metadata.labels"
var fooarr = foo.split(".")
var bar={
metadata:{
labels: "foobar"
}
}
var temp = oof
for(lm of lmaoarr){
temp = temp[lm]
}
console.log(temp)How do I do something similar using client-go?
The standard kubelet code has logic to translate the downward API fields into environment variables. It is neither simple nor generic, though: at the bottom of the stack, only the specific fields listed in the Kubernetes documentation are supported. It would be incomplete, but not wrong or inconsistent with standard Kubernetes, to just match on these specific fields:
for _, item := range downwardApiObject.Items {
switch item.FieldPath.FieldRef {
case "metadata.name":
return pod.ObjectMeta.Name
}
}
The actual code:
pods.ConvertDownwardAPIFieldLabel which does some very lightweight normalization and validation: subscripts are only allowed on metadata.annotations and metadata.labels, only the dozen or so specific field names are allowed, and spec.host is rewritten to spec.nodeName.spec.* and status.* variables that depend on non-metadata fields in the pod spec or runtime data.fieldpath.ExtractFieldPathAsString which knows how to handle the metadata.* variables.The k8s.io/kubernetes/pkg/fieldpath 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 fieldpath.ExtractFieldPathAsString passing it the Pod object, which will handle the metadata fields but nothing else.