Как десериализовать файл YAML Kubernetes

Как я могу десериализовать YAML-файл Kubernetes в структуру Go? Я посмотрел в kubectl код, но почему-то я получаю сообщение об ошибке для каждого файла YAML:

no kind "Deployment" is registered for version "apps/v1beta1"

Это 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)
}

Я использую версию клиента 2.0.0, glide.yaml выглядит так:

package: test/stackru
import:
- package: k8s.io/client-go
  version: ^2.0.0

Это ссылки на kubectl:

К сожалению, документы меня очень смущают, поэтому я понятия не имею, как решить эту проблему.

Редактировать:

Эта проблема также существует с другими типами ресурсов:

  • no kind "Service" is registered for version "v1"

3 ответа

Решение

Вам нужно импортировать _ "k8s.io/client-go/pkg/apis/extensions/install" в противном случае схема пуста, см. также документы.

Полный рабочий пример:

$ go get -u github.com/golang/dep/cmd/dep
$ dep init
$ go run main.go

Со следующим 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)
}

Обратите внимание, что я также импортировал _ "k8s.io/client-go/pkg/api/install" для вас, чтобы вы могли использовать объекты в v1 такие как стручки или услуги.

РЕДАКТИРОВАТЬ: Слава моему коллеге Стефану Шимански, который предложил первоначальное решение.

Я использую оборудование APIk8s.io/apimachinery/pkg/util/yaml расшифровывать манифесты развертывания и обслуживания kubernete.

d := &appsv1.Deployment{}
dec := k8Yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(deploymentManifest)), 1000)

if err := dec.Decode(&d); err != nil {
        return nil, err
}

fmt.Pritnln("%+v", d)
      import (
    "fmt"
    "gopkg.in/yaml.v2"
    "log"
    //corev1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/runtime/serializer/json"
    "k8s.io/client-go/kubernetes/scheme"
    v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
)

....

func ParseYaml2(yaml []byte) (v1alpha1.Application, error) {
    // Create a YAML serializer.  JSON is a subset of YAML, so is supported too.
    s := json.NewYAMLSerializer(json.DefaultMetaFactory, scheme.Scheme,
        scheme.Scheme)

    // Decode the YAML to an object.
    var app v1alpha1.Application
    _, _, err := s.Decode(yaml, nil, &app)
    if err != nil {
        panic(err)
    }
    //fmt.Printf("%#v\n", app)
    return app, err
}
---
go.mod
// https://github.com/argoproj/argo-cd/issues/4055
replace github.com/argoproj/argo-cd => github.com/argoproj/argo-cd v1.5.5

var yaml2 = []byte(`
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
...

var app v1alpha1.Application
app,err := ParseYaml2(yaml2)
// Types from https://github.com/argoproj/argo-cd/blob/master/pkg/apis/application/v1alpha1/types.go
    fmt.Printf("--- t:\n%s\n\n", app.Spec.Source.Path)
    fmt.Printf("--- t:\n%s\n\n", app.Spec.Source.Helm.ValueFiles)
----
Другие вопросы по тегам