Skip to content

Commit

Permalink
Add ability to yaml-encode unstructured
Browse files Browse the repository at this point in the history
This is not only cleaner (eliminate a function that panics), but adds
the ability to marshal unstructured.
  • Loading branch information
justinsb committed Sep 10, 2021
1 parent 89a9a4a commit cde8a61
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
2 changes: 1 addition & 1 deletion pkg/kopscodecs/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 25 additions & 20 deletions pkg/kopscodecs/codecs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import (
"regexp"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/klog/v2"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/install"
"k8s.io/kops/pkg/apis/kops/v1alpha2"
Expand All @@ -40,14 +40,6 @@ func init() {
install.Install(Scheme)
}

func encoder(gv runtime.GroupVersioner, mediaType string) runtime.Encoder {
e, ok := runtime.SerializerInfoForMediaType(Codecs.SupportedMediaTypes(), mediaType)
if !ok {
klog.Fatalf("no %s serializer registered", mediaType)
}
return Codecs.EncoderForVersion(e.Serializer, gv)
}

func decoder() runtime.Decoder {
// TODO: Cache?
// Codecs provides access to encoding and decoding for the scheme
Expand All @@ -60,29 +52,42 @@ func ToVersionedYaml(obj runtime.Object) ([]byte, error) {
return ToVersionedYamlWithVersion(obj, v1alpha2.SchemeGroupVersion)
}

// ToVersionedYamlWithVersion encodes the object to YAML, in a specified API version
func ToVersionedYamlWithVersion(obj runtime.Object, version runtime.GroupVersioner) ([]byte, error) {
// ToMediaTypeWithVersion encodes the object to the specified mediaType, in a specified API version
func ToMediaTypeWithVersion(obj runtime.Object, mediaType string, gv runtime.GroupVersioner) ([]byte, error) {
e, ok := runtime.SerializerInfoForMediaType(Codecs.SupportedMediaTypes(), mediaType)
if !ok {
return nil, fmt.Errorf("no serializer for %q", mediaType)
}

_, isUnstructured := obj.(*unstructured.Unstructured)
var w bytes.Buffer
err := encoder(version, "application/yaml").Encode(obj, &w)
if err != nil {
return nil, fmt.Errorf("error encoding %T: %v", obj, err)
if isUnstructured {
err := e.Serializer.Encode(obj, &w)
if err != nil {
return nil, fmt.Errorf("error encoding %T with unstructured encoder: %w", obj, err)
}
} else {
encoder := Codecs.EncoderForVersion(e.Serializer, gv)
if err := encoder.Encode(obj, &w); err != nil {
return nil, fmt.Errorf("error encoding %T with structured encoder: %w", obj, err)
}
}
return w.Bytes(), nil
}

// ToVersionedYamlWithVersion encodes the object to YAML, in a specified API version
func ToVersionedYamlWithVersion(obj runtime.Object, version runtime.GroupVersioner) ([]byte, error) {
return ToMediaTypeWithVersion(obj, "application/yaml", version)
}

// ToVersionedJSON encodes the object to JSON
func ToVersionedJSON(obj runtime.Object) ([]byte, error) {
return ToVersionedJSONWithVersion(obj, v1alpha2.SchemeGroupVersion)
}

// ToVersionedJSONWithVersion encodes the object to JSON, in a specified API version
func ToVersionedJSONWithVersion(obj runtime.Object, version runtime.GroupVersioner) ([]byte, error) {
var w bytes.Buffer
err := encoder(version, "application/json").Encode(obj, &w)
if err != nil {
return nil, fmt.Errorf("error encoding %T: %v", obj, err)
}
return w.Bytes(), nil
return ToMediaTypeWithVersion(obj, "application/json", version)
}

// Decode decodes the specified data, with the specified default version
Expand Down

0 comments on commit cde8a61

Please sign in to comment.