diff --git a/cmd/decode.go b/cmd/decode.go index 6f83acd..7863e9b 100644 --- a/cmd/decode.go +++ b/cmd/decode.go @@ -151,12 +151,11 @@ func runInBatchMode(metaOnly bool, outMediaType string, out io.Writer) (err erro continue } - buf := bytes.NewBufferString("") - _, err = encoding.Convert(scheme.Codecs, inMediaType, outMediaType, decodedinput, buf) + buf, _, err := encoding.Convert(scheme.Codecs, inMediaType, outMediaType, decodedinput) if err != nil { fmt.Fprintf(out, "ERROR:%v|\n", err) } else { - fmt.Fprintf(out, "OK|%s\n", buf.String()) + fmt.Fprintf(out, "OK|%s\n", string(buf)) } lineNum++ @@ -174,7 +173,12 @@ func run(metaOnly bool, outMediaType string, in []byte, out io.Writer) error { return encoding.DecodeSummary(inMediaType, in, out) } - _, err = encoding.Convert(scheme.Codecs, inMediaType, outMediaType, in, out) + buf, _, err := encoding.Convert(scheme.Codecs, inMediaType, outMediaType, in) + if err != nil { + return err + } + + _, err = out.Write(buf) return err } diff --git a/cmd/encode.go b/cmd/encode.go index 41536ae..f8f43eb 100644 --- a/cmd/encode.go +++ b/cmd/encode.go @@ -81,6 +81,10 @@ func encodeValidateAndRun() error { // encodeRun runs the encode command. func encodeRun(inMediaType string, in []byte, out io.Writer) error { - _, err := encoding.Convert(scheme.Codecs, inMediaType, encoding.StorageBinaryMediaType, in, out) + buf, _, err := encoding.Convert(scheme.Codecs, inMediaType, encoding.StorageBinaryMediaType, in) + if err != nil { + return err + } + _, err = out.Write(buf) return err } diff --git a/cmd/extract.go b/cmd/extract.go index efbb7ab..2103e83 100644 --- a/cmd/extract.go +++ b/cmd/extract.go @@ -222,7 +222,11 @@ func printValue(filename string, key string, version string, raw bool, outMediaT fmt.Fprintf(out, "%s\n", string(in)) return nil } - _, err = encoding.DetectAndConvert(scheme.Codecs, outMediaType, in, out) + buf, _, err := encoding.DetectAndConvert(scheme.Codecs, outMediaType, in) + if err != nil { + return err + } + _, err = out.Write(buf) return err } @@ -244,7 +248,11 @@ func printLeafItemSummary(kv *mvccpb.KeyValue, out io.Writer) error { // printLeafItemValue prints an etcd value for a given boltdb leaf item. func printLeafItemValue(kv *mvccpb.KeyValue, outMediaType string, out io.Writer) error { - _, err := encoding.DetectAndConvert(scheme.Codecs, outMediaType, kv.Value, out) + buf, _, err := encoding.DetectAndConvert(scheme.Codecs, outMediaType, kv.Value) + if err != nil { + return err + } + _, err = out.Write(buf) return err } diff --git a/pkg/data/data.go b/pkg/data/data.go index 9231511..e4f82fb 100644 --- a/pkg/data/data.go +++ b/pkg/data/data.go @@ -228,12 +228,12 @@ func ListKeySummaries(codecs serializer.CodecFactory, filename string, filters [ if prefixAllowed { ks, ok := m[string(kv.Key)] if !ok { - buf := new(bytes.Buffer) + var buf []byte var valJson string var typeMeta *runtime.TypeMeta var err error - if typeMeta, err = encoding.DetectAndConvert(codecs, encoding.JsonMediaType, kv.Value, buf); err == nil { - valJson = strings.TrimSpace(buf.String()) + if buf, typeMeta, err = encoding.DetectAndConvert(codecs, encoding.JsonMediaType, kv.Value); err == nil { + valJson = strings.TrimSpace(string(buf)) } var key string var value map[string]interface{} diff --git a/pkg/encoding/encoding.go b/pkg/encoding/encoding.go index e8fc3c3..14d8606 100644 --- a/pkg/encoding/encoding.go +++ b/pkg/encoding/encoding.go @@ -60,28 +60,32 @@ func ToMediaType(out string) (string, error) { // DetectAndConvert first detects the media type of the in param data and then converts it from // the kv store encoded data to the given output format using kubernetes' api machinery to // perform the conversion. -func DetectAndConvert(codecs serializer.CodecFactory, outMediaType string, in []byte, out io.Writer) (*runtime.TypeMeta, error) { +func DetectAndConvert(codecs serializer.CodecFactory, outMediaType string, in []byte) ([]byte, *runtime.TypeMeta, error) { inMediaType, in, err := DetectAndExtract(in) if err != nil { - return nil, err + return nil, nil, err } - return Convert(codecs, inMediaType, outMediaType, in, out) + return Convert(codecs, inMediaType, outMediaType, in) } // Convert from kv store encoded data to the given output format using kubernetes' api machinery to // perform the conversion. -func Convert(codecs serializer.CodecFactory, inMediaType, outMediaType string, in []byte, out io.Writer) (*runtime.TypeMeta, error) { +func Convert(codecs serializer.CodecFactory, inMediaType, outMediaType string, in []byte) ([]byte, *runtime.TypeMeta, error) { if inMediaType == StorageBinaryMediaType && outMediaType == ProtobufMediaType { - return nil, DecodeRaw(in, out) + unknown, err := DecodeUnknown(in) + if err != nil { + return nil, nil, err + } + return unknown.Raw, &unknown.TypeMeta, nil } if inMediaType == ProtobufMediaType && outMediaType == StorageBinaryMediaType { - return nil, fmt.Errorf("unsupported conversion: protobuf to kubernetes binary storage representation") + return nil, nil, fmt.Errorf("unsupported conversion: protobuf to kubernetes binary storage representation") } typeMeta, err := decodeTypeMeta(inMediaType, in) if err != nil { - return nil, err + return nil, nil, err } var encoded []byte @@ -94,29 +98,25 @@ func Convert(codecs serializer.CodecFactory, inMediaType, outMediaType string, i } else { inCodec, err := newCodec(codecs, typeMeta, inMediaType) if err != nil { - return nil, err + return nil, nil, err } outCodec, err := newCodec(codecs, typeMeta, outMediaType) if err != nil { - return nil, err + return nil, nil, err } obj, err := runtime.Decode(inCodec, in) if err != nil { - return nil, fmt.Errorf("error decoding from %s: %s", inMediaType, err) + return nil, nil, fmt.Errorf("error decoding from %s: %s", inMediaType, err) } encoded, err = runtime.Encode(outCodec, obj) if err != nil { - return nil, fmt.Errorf("error encoding to %s: %s", outMediaType, err) + return nil, nil, fmt.Errorf("error encoding to %s: %s", outMediaType, err) } } - _, err = out.Write(encoded) - if err != nil { - return nil, err - } - return typeMeta, nil + return encoded, typeMeta, nil } // DetectAndExtract searches the the start of either json of protobuf data, and, if found, returns the mime type and data. @@ -165,20 +165,6 @@ func tryFindJson(in []byte) (*json.RawMessage, bool) { return nil, false } -// DecodeRaw decodes the raw payload bytes contained within the 'Unknown' protobuf envelope of -// the given storage data. -func DecodeRaw(in []byte, out io.Writer) error { - unknown, err := DecodeUnknown(in) - if err != nil { - return err - } - _, err = out.Write(unknown.Raw) - if err != nil { - return fmt.Errorf("failed to write output: %v", err) - } - return nil -} - // DecodeSummary decodes the TypeMeta, ContentEncoding and ContentType fields from the 'Unknown' // protobuf envelope of the given storage data. func DecodeSummary(inMediaType string, in []byte, out io.Writer) error {