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-info
Using 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.