<p>How can I deserialize a Kubernetes YAML file into an Go struct? I took a look into the <code>kubectl</code> code, but somehow I get an error for every YAML file:</p>

<pre><code>no kind "Deployment" is registered for version "apps/v1beta1"
</code></pre>

<p>This is an MWE:</p>

<pre><code>package main

import (
    "fmt"

    "k8s.io/client-go/pkg/api"
)

var service = `
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
`

func main() {
    decode := api.Codecs.UniversalDecoder().Decode
    //decode := api.Codecs.UniversalDeserializer().Decode

    obj, _, err := decode([]byte(service), nil, nil)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v\n", obj)
}
</code></pre>

<p>I am using client version <code>2.0.0</code>. The <code>glide.yaml</code> looks like this:</p>

<pre><code>package: test/stackoverflow
import:
- package: k8s.io/client-go
  version: ^2.0.0
</code></pre>

<p>These are the references to <code>kubectl</code>:</p>

<ul>
<li><a href="https://github.com/kubernetes/kubernetes/blob/43ac38e29e6ecf83e78bc7c5d9f804310b051c95/pkg/kubectl/cmd/apply.go#L637" rel="noreferrer">https://github.com/kubernetes/kubernetes/blob/43ac38e29e6ecf83e78bc7c5d9f804310b051c95/pkg/kubectl/cmd/apply.go#L637</a></li>
<li><a href="https://github.com/kubernetes/kubernetes/blob/43ac38e29e6ecf83e78bc7c5d9f804310b051c95/pkg/kubectl/cmd/util/factory_client_access.go#L205-L213" rel="noreferrer">https://github.com/kubernetes/kubernetes/blob/43ac38e29e6ecf83e78bc7c5d9f804310b051c95/pkg/kubectl/cmd/util/factory_client_access.go#L205-L213</a></li>
</ul>

<p>Unfortunately, the <a href="https://godoc.org/k8s.io/client-go" rel="noreferrer">docs</a> are very confusing to me, so I have no idea how to tackle this problem.</p>

<p><strong>Edit:</strong></p>

<p>This problem also exists with other resource types:</p>

<ul>
<li><code>no kind "Service" is registered for version "v1"</code></li>
</ul>

<p>You need to import <code>_ "k8s.io/client-go/pkg/apis/extensions/install"</code> otherwise the schema is empty, see also <a href="https://godoc.org/k8s.io/client-go/pkg/apis/extensions/install" rel="noreferrer">docs</a>.</p>

<p>The complete working example is:</p>

<pre><code>$ go get -u github.com/golang/dep/cmd/dep
$ dep init
$ go run main.go
</code></pre>

<p>With the following <code>main.go</code>:</p>

<pre><code>package main

import (
    "fmt"

    "k8s.io/client-go/pkg/api"
    _ "k8s.io/client-go/pkg/api/install"
    _ "k8s.io/client-go/pkg/apis/extensions/install"
)

var deployment = `
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
template:
  metadata:
    labels:
      run: my-nginx
  spec:
    containers:
    - name: my-nginx
      image: nginx
      ports:
      - containerPort: 80
`

func main() {
    // decode := api.Codecs.UniversalDecoder().Decode
    decode := api.Codecs.UniversalDeserializer().Decode

    obj, _, err := decode([]byte(deployment), nil, nil)
    if err != nil {
        fmt.Printf("%#v", err)
    }

    fmt.Printf("%#v\n", obj)
}
</code></pre>

<p>Note that I also imported <code>_ "k8s.io/client-go/pkg/api/install"</code> for you so that you can use objects in <code>v1</code> such as pods or services.</p>

<p>EDIT: Kudos to my colleague <a href="https://twitter.com/the1stein" rel="noreferrer">Stefan Schimanski</a> who proposed the initial solution.</p>
