How can I deserialize a Kubernetes YAML file into an Go struct? I took a look into the kubectl
code, but somehow I get an error for every YAML file:
no kind "Deployment" is registered for version "apps/v1beta1"
This is an MWE:
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)
}
I am using client version 2.0.0
. The glide.yaml
looks like this:
package: test/stackoverflow
import:
- package: k8s.io/client-go
version: ^2.0.0
These are the references to kubectl
:
Unfortunately, the docs are very confusing to me, so I have no idea how to tackle this problem.
Edit:
This problem also exists with other resource types:
no kind "Service" is registered for version "v1"
You need to import _ "k8s.io/client-go/pkg/apis/extensions/install"
otherwise the schema is empty, see also docs.
The complete working example is:
$ go get -u github.com/golang/dep/cmd/dep
$ dep init
$ go run main.go
With the following main.go
:
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)
}
Note that I also imported _ "k8s.io/client-go/pkg/api/install"
for you so that you can use objects in v1
such as pods or services.
EDIT: Kudos to my colleague Stefan Schimanski who proposed the initial solution.
I've been using api machinery'sk8s.io/apimachinery/pkg/util/yaml
to decode kubernete's deployment and service manifests.
import (
"fmt"
"bytes"
appsv1 "k8s.io/api/apps/v1"
k8Yaml "k8s.io/apimachinery/pkg/util/yaml"
)
...
d := &appsv1.Deployment{}
dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(deploymentManifest)), 1000)
if err := dec.Decode(&d); err != nil {
return nil, err
}
fmt.Printf("%+v", d)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With