i'm new in go, i can't find a way to unmarshal a yaml using "gopkg.in/yaml.v2" I suppose the error is in the way i define the struct.
I need to parse a kubernetes job yaml and edit in go to generate an update yaml. The structure is almost static but have two lists in wich the keys could have different things inside.
I reduced the yaml to one listes (volumes) to simplify the example.
apiVersion: batch/v1
kind: Job
metadata:
name: jobname
namespace: namespace
spec:
ttlSecondsAfterFinished: 86400
template:
spec:
containers:
- name: container-name
image: containerimage:tag
command:
- php
- cli/migrations.php
- up
restartPolicy: Never
volumes:
- name: filestore
persistentVolumeClaim:
claimName: data-pvc
readOnly: false
- name: stackdriver
secret:
secretName: stackdriver-prod
backoffLimit: 1
those are my structs definitions:
type PersistentVolumeClaims struct {
ClaimName string `yaml:"claimName,omitempty"`
ReadOnly bool `yaml:"readOnly,omitempty"`
}
type Secrets struct {
SecretName string `yaml:"secretName,omitempty"`
}
type Names struct {
Name string `yaml:"name"`
PersistentVolumeClaim PersistentVolumeClaims `yaml:"persistentVolumeClaim,omitempty"`
Secret Secrets `yaml:"secret,omitempty"`
}
type Jobs struct {
ApiVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata struct {
Name string `yaml:"name"`
Namespace string `yaml:"namespace"`
}
Spec struct {
TtlSecondsAfterFinished int `yaml:"ttlSecondsAfterFinished"`
Template struct {
Spec struct {
Containers []struct {
Name string
Image string `yaml:"image"`
Command []string `yaml:"command"`
VolumeMounts []struct {
Name string
SubPath string `yaml:"subPath"`
MountPath string `yaml:"mountPath"`
ReadOnly bool `yaml:"readOnly"`
}
RestartPolicy string `yaml:"restartPolicy"`
}
Volumes map[string][]Names
}
BackoffLimit int `yaml:"backoffLimit"`
}
}
}
i tried different structures but i don't get the solution. Any help will be appreciated.
--- SOLVED
I have redone the tool using the official go-client https://github.com/kubernetes/client-go as suggested by Jonas. Now everything work!
I need to parse a kubernetes job yaml and edit in go to generate an update yaml. The structure is almost static but have two lists in wich the keys could have different things inside.
It sound like your application is running in a cluster, want to retrieve a Job
, modify it and then update it.
I would recommend the official Kubernetes client-go for this. It has libraries for Kubernetes resources like Job
. See the example using a Deployment
You can use the official structs from the Kubernetes APIs. If you still want to declare the structs: Your yaml tags are incomplete. You do not have tags for nested structs:
type Jobs struct {
Metadata struct {
Name string `yaml:"name"`
Namespace string `yaml:"namespace"`
} `yaml:"metadata"` // Here is one
Spec struct {
TtlSecondsAfterFinished int `yaml:"ttlSecondsAfterFinished"`
Template struct {
Spec struct {
Containers []struct {
VolumeMounts []struct {
Name string
SubPath string `yaml:"subPath"`
MountPath string `yaml:"mountPath"`
ReadOnly bool `yaml:"readOnly"`
} `yaml:"volumeMounts"` // Here is another
} `yaml:"containers"` // Here is another
Volumes map[string][]Names `yaml:"volumes"` // This is missin as well
} `yaml:"spec"` //
} `yaml:"template"` //
} `yaml:"spec"` //
}
Suppose that your data is in the file example.yaml
; you can unmarshall into a struct using gopkg.in/yaml.v2
like
package main
import (
"fmt"
"log"
"io/ioutil"
"gopkg.in/yaml.v2"
)
type item struct {
ItemA string `yaml:"item_a"`
ItemB string `yaml:"item_b"`
}
func read(filename string) (item, error) {
var output item
content, err := ioutil.ReadFile(filename)
if err != nil {
return item{}, err
}
err = yaml.Unmarshal(content, output)
if err != nil {
return item{}, err
}
return output, nil
}
func main() {
output, err := read("example.yaml")
if err != nil {
log.Fatal(err)
}
fmt.Println("output: ", output)
}