<p><strong>TL;DR:</strong> How can I flexibly decode a k8s API object and inspect its top-level <code>metav1.ObjectMeta</code> struct without knowing the object's <code>Kind</code> in advance?</p>

<hr>

<p>I'm writing an admission controller endpoint that unmarshals a <code>metav1.AdmissionReview</code> object's <code>Request.Object.Raw</code> field into a concrete object based on the <code>Request.Kind</code> field - e.g.</p>

<pre class="lang-golang prettyprint-override"><code>if kind == "Pod" {
    var pod core.Pod
    // ...
    if _, _, err := deserializer.Decode(admissionReview.Request.Object.Raw, nil, &amp;pod); err != nil {
        return nil, err
    }

    annotations := pod.ObjectMeta.Annotations
    // inspect/validate the annotations...
</code></pre>

<p>This requires knowing all possible types up front, or perhaps asking a user to supply a <code>map[kind]corev1.Object</code> that we can use to be more flexible.</p>

<p>What I'd like to instead achieve is something closer to:</p>

<pre class="lang-golang prettyprint-override"><code>var objMeta core.ObjectMeta
if _, _, err := deserializer.Decode(admissionReview.Request.Object.Raw, nil, &amp;objMeta); err != nil {
        return nil, err
}

// if objMeta is populated, validate the fields, else
// assume it is an object that does not define an ObjectMeta
// as part of its schema.
</code></pre>

<p>Is this possible? The k8s API surface is fairly extensive, and I've crawled through the <a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Object" rel="noreferrer">metav1 godoc</a>, corev1 godoc &amp; <a href="https://cs.k8s.io" rel="noreferrer">https://cs.k8s.io</a> for prior art without a decent example.</p>

<p>The closest I've found is possibly the <a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMetaAccessor" rel="noreferrer"><code>ObjectMetaAccessor</code></a> interface, but I'd need to get from an <code>AdmissionReview.Request.Object</code> (type <code>runtime.RawExtension</code>) to a <code>runtime.Object</code> first.</p>

<p>I believe you can't find what you are looking for because, when decoding an object, Kubernetes uses <a href="https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/interfaces.go#L255" rel="nofollow noreferrer">GetObjectKind</a> and compares the result to a <a href="https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/scheme.go#L32" rel="nofollow noreferrer">Scheme</a> to convert the object to a concrete type, rather than using some <a href="https://en.wikipedia.org/wiki/Generic_programming" rel="nofollow noreferrer">generic</a> like approach and interacting with the fields of an object without knowing it's concrete type.</p>
<p>So you can use reflection instead, something like:</p>
<pre><code>k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()
k8sObjObjectMeta := k8sObjValue.FieldByName(&quot;ObjectMeta&quot;)
annotations, ok := k8sObjObjectMeta.FieldByName(&quot;Annotations&quot;).Interface().(map[string]string)
if !ok {
    panic(&quot;failed to retrieve annotations&quot;)
}
</code></pre>
<p>EDIT:</p>
<p>Or closer to your requirements, convert to an ObjectMeta object</p>
<pre><code>k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()
objMeta, ok := k8sObjValue.FieldByName(&quot;ObjectMeta&quot;).Interface().(core.ObjectMeta)
if !ok {
    panic(&quot;failed to retrieve object metadata&quot;)
}
</code></pre>
