mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Implement Encoder.Identifier() method
This commit is contained in:
parent
36300c8c9f
commit
cd4215ad8b
@ -44,6 +44,7 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// NestedFieldCopy returns a deep copy of the value of a nested field.
|
||||
@ -329,6 +330,8 @@ var UnstructuredJSONScheme runtime.Codec = unstructuredJSONScheme{}
|
||||
|
||||
type unstructuredJSONScheme struct{}
|
||||
|
||||
const unstructuredJSONSchemeIdentifier runtime.Identifier = "unstructuredJSON"
|
||||
|
||||
func (s unstructuredJSONScheme) Decode(data []byte, _ *schema.GroupVersionKind, obj runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
var err error
|
||||
if obj != nil {
|
||||
@ -373,6 +376,11 @@ func (unstructuredJSONScheme) Encode(obj runtime.Object, w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (unstructuredJSONScheme) Identifier() runtime.Identifier {
|
||||
return unstructuredJSONSchemeIdentifier
|
||||
}
|
||||
|
||||
func (s unstructuredJSONScheme) decode(data []byte) (runtime.Object, error) {
|
||||
type detector struct {
|
||||
Items gojson.RawMessage
|
||||
@ -461,16 +469,28 @@ func (s unstructuredJSONScheme) decodeToList(data []byte, list *UnstructuredList
|
||||
}
|
||||
|
||||
type jsonFallbackEncoder struct {
|
||||
encoder runtime.Encoder
|
||||
encoder runtime.Encoder
|
||||
identifier runtime.Identifier
|
||||
}
|
||||
|
||||
func NewJSONFallbackEncoder(encoder runtime.Encoder) runtime.Encoder {
|
||||
result := map[string]string{
|
||||
"name": "fallback",
|
||||
"base": string(encoder.Identifier()),
|
||||
}
|
||||
identifier, err := gojson.Marshal(result)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed marshaling identifier for jsonFallbackEncoder: %v", err)
|
||||
}
|
||||
return &jsonFallbackEncoder{
|
||||
encoder: encoder,
|
||||
encoder: encoder,
|
||||
identifier: runtime.Identifier(identifier),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *jsonFallbackEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
// There is no need to handle runtime.CacheableObject, as we only
|
||||
// fallback to other encoders here.
|
||||
err := c.encoder.Encode(obj, w)
|
||||
if runtime.IsNotRegisteredError(err) {
|
||||
switch obj.(type) {
|
||||
@ -480,3 +500,8 @@ func (c *jsonFallbackEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (c *jsonFallbackEncoder) Identifier() runtime.Identifier {
|
||||
return c.identifier
|
||||
}
|
||||
|
@ -104,10 +104,17 @@ type NoopEncoder struct {
|
||||
|
||||
var _ Serializer = NoopEncoder{}
|
||||
|
||||
const noopEncoderIdentifier Identifier = "noop"
|
||||
|
||||
func (n NoopEncoder) Encode(obj Object, w io.Writer) error {
|
||||
return fmt.Errorf("encoding is not allowed for this codec: %v", reflect.TypeOf(n.Decoder))
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (n NoopEncoder) Identifier() Identifier {
|
||||
return noopEncoderIdentifier
|
||||
}
|
||||
|
||||
// NoopDecoder converts an Encoder to a Serializer or Codec for code that expects them but only uses encoding.
|
||||
type NoopDecoder struct {
|
||||
Encoder
|
||||
@ -197,10 +204,30 @@ func (c *parameterCodec) EncodeParameters(obj Object, to schema.GroupVersion) (u
|
||||
type base64Serializer struct {
|
||||
Encoder
|
||||
Decoder
|
||||
|
||||
identifier Identifier
|
||||
}
|
||||
|
||||
func NewBase64Serializer(e Encoder, d Decoder) Serializer {
|
||||
return &base64Serializer{e, d}
|
||||
return &base64Serializer{
|
||||
Encoder: e,
|
||||
Decoder: d,
|
||||
identifier: identifier(e),
|
||||
}
|
||||
}
|
||||
|
||||
func identifier(e Encoder) Identifier {
|
||||
result := map[string]string{
|
||||
"name": "base64",
|
||||
}
|
||||
if e != nil {
|
||||
result["encoder"] = string(e.Identifier())
|
||||
}
|
||||
identifier, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed marshaling identifier for base64Serializer: %v", err)
|
||||
}
|
||||
return Identifier(identifier)
|
||||
}
|
||||
|
||||
func (s base64Serializer) Encode(obj Object, stream io.Writer) error {
|
||||
@ -210,6 +237,11 @@ func (s base64Serializer) Encode(obj Object, stream io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (s base64Serializer) Identifier() Identifier {
|
||||
return s.identifier
|
||||
}
|
||||
|
||||
func (s base64Serializer) Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) {
|
||||
out := make([]byte, base64.StdEncoding.DecodedLen(len(data)))
|
||||
n, err := base64.StdEncoding.Decode(out, data)
|
||||
|
@ -36,6 +36,7 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//vendor/github.com/json-iterator/go:go_default_library",
|
||||
"//vendor/github.com/modern-go/reflect2:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
|
||||
"k8s.io/apimachinery/pkg/util/framer"
|
||||
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// NewSerializer creates a JSON serializer that handles encoding versioned objects into the proper JSON form. If typer
|
||||
@ -53,13 +54,28 @@ func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer ru
|
||||
// and are immutable.
|
||||
func NewSerializerWithOptions(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, options SerializerOptions) *Serializer {
|
||||
return &Serializer{
|
||||
meta: meta,
|
||||
creater: creater,
|
||||
typer: typer,
|
||||
options: options,
|
||||
meta: meta,
|
||||
creater: creater,
|
||||
typer: typer,
|
||||
options: options,
|
||||
identifier: identifier(options),
|
||||
}
|
||||
}
|
||||
|
||||
// identifier computes Identifier of Encoder based on the given options.
|
||||
func identifier(options SerializerOptions) runtime.Identifier {
|
||||
result := map[string]string{
|
||||
"name": "json",
|
||||
"yaml": strconv.FormatBool(options.Yaml),
|
||||
"pretty": strconv.FormatBool(options.Pretty),
|
||||
}
|
||||
identifier, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed marshaling identifier for json Serializer: %v", err)
|
||||
}
|
||||
return runtime.Identifier(identifier)
|
||||
}
|
||||
|
||||
// SerializerOptions holds the options which are used to configure a JSON/YAML serializer.
|
||||
// example:
|
||||
// (1) To configure a JSON serializer, set `Yaml` to `false`.
|
||||
@ -85,6 +101,8 @@ type Serializer struct {
|
||||
options SerializerOptions
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.ObjectTyper
|
||||
|
||||
identifier runtime.Identifier
|
||||
}
|
||||
|
||||
// Serializer implements Serializer
|
||||
@ -311,6 +329,11 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return encoder.Encode(obj)
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (s *Serializer) Identifier() runtime.Identifier {
|
||||
return s.identifier
|
||||
}
|
||||
|
||||
// RecognizesData implements the RecognizingDecoder interface.
|
||||
func (s *Serializer) RecognizesData(peek io.Reader) (ok, unknown bool, err error) {
|
||||
if s.options.Yaml {
|
||||
|
@ -86,6 +86,8 @@ type Serializer struct {
|
||||
var _ runtime.Serializer = &Serializer{}
|
||||
var _ recognizer.RecognizingDecoder = &Serializer{}
|
||||
|
||||
const serializerIdentifier runtime.Identifier = "protobuf"
|
||||
|
||||
// Decode attempts to convert the provided data into a protobuf message, extract the stored schema kind, apply the provided default
|
||||
// gvk, and then load that data into an object matching the desired schema kind or the provided into. If into is *runtime.Unknown,
|
||||
// the raw data will be extracted and no decoding will be performed. If into is not registered with the typer, then the object will
|
||||
@ -245,6 +247,11 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (s *Serializer) Identifier() runtime.Identifier {
|
||||
return serializerIdentifier
|
||||
}
|
||||
|
||||
// RecognizesData implements the RecognizingDecoder interface.
|
||||
func (s *Serializer) RecognizesData(peek io.Reader) (bool, bool, error) {
|
||||
prefix := make([]byte, 4)
|
||||
@ -321,6 +328,8 @@ type RawSerializer struct {
|
||||
|
||||
var _ runtime.Serializer = &RawSerializer{}
|
||||
|
||||
const rawSerializerIdentifier runtime.Identifier = "raw-protobuf"
|
||||
|
||||
// Decode attempts to convert the provided data into a protobuf message, extract the stored schema kind, apply the provided default
|
||||
// gvk, and then load that data into an object matching the desired schema kind or the provided into. If into is *runtime.Unknown,
|
||||
// the raw data will be extracted and no decoding will be performed. If into is not registered with the typer, then the object will
|
||||
@ -460,6 +469,11 @@ func (s *RawSerializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (s *RawSerializer) Identifier() runtime.Identifier {
|
||||
return rawSerializerIdentifier
|
||||
}
|
||||
|
||||
var LengthDelimitedFramer = lengthDelimitedFramer{}
|
||||
|
||||
type lengthDelimitedFramer struct{}
|
||||
|
@ -31,6 +31,7 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -17,12 +17,14 @@ limitations under the License.
|
||||
package versioning
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// NewDefaultingCodecForScheme is a convenience method for callers that are using a scheme.
|
||||
@ -62,6 +64,8 @@ func NewCodec(
|
||||
encodeVersion: encodeVersion,
|
||||
decodeVersion: decodeVersion,
|
||||
|
||||
identifier: identifier(encodeVersion, encoder),
|
||||
|
||||
originalSchemeName: originalSchemeName,
|
||||
}
|
||||
return internal
|
||||
@ -78,10 +82,30 @@ type codec struct {
|
||||
encodeVersion runtime.GroupVersioner
|
||||
decodeVersion runtime.GroupVersioner
|
||||
|
||||
identifier runtime.Identifier
|
||||
|
||||
// originalSchemeName is optional, but when filled in it holds the name of the scheme from which this codec originates
|
||||
originalSchemeName string
|
||||
}
|
||||
|
||||
// identifier computes Identifier of Encoder based on codec parameters.
|
||||
func identifier(encodeGV runtime.GroupVersioner, encoder runtime.Encoder) runtime.Identifier {
|
||||
result := map[string]string{
|
||||
"name": "versioning",
|
||||
}
|
||||
if encodeGV != nil {
|
||||
result["encodeGV"] = encodeGV.Identifier()
|
||||
}
|
||||
if encoder != nil {
|
||||
result["encoder"] = string(encoder.Identifier())
|
||||
}
|
||||
identifier, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed marshaling identifier for codec: %v", err)
|
||||
}
|
||||
return runtime.Identifier(identifier)
|
||||
}
|
||||
|
||||
// Decode attempts a decode of the object, then tries to convert it to the internal version. If into is provided and the decoding is
|
||||
// successful, the returned runtime.Object will be the value passed as into. Note that this may bypass conversion if you pass an
|
||||
// into that matches the serialized version.
|
||||
@ -230,3 +254,8 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
// Conversion is responsible for setting the proper group, version, and kind onto the outgoing object
|
||||
return c.encoder.Encode(out, w)
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (c *codec) Identifier() runtime.Identifier {
|
||||
return c.identifier
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ go_library(
|
||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -18,10 +18,12 @@ package discovery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
const APIGroupPrefix = "/apis"
|
||||
@ -36,6 +38,29 @@ func keepUnversioned(group string) bool {
|
||||
type stripVersionEncoder struct {
|
||||
encoder runtime.Encoder
|
||||
serializer runtime.Serializer
|
||||
identifier runtime.Identifier
|
||||
}
|
||||
|
||||
func newStripVersionEncoder(e runtime.Encoder, s runtime.Serializer) runtime.Encoder {
|
||||
return stripVersionEncoder{
|
||||
encoder: e,
|
||||
serializer: s,
|
||||
identifier: identifier(e),
|
||||
}
|
||||
}
|
||||
|
||||
func identifier(e runtime.Encoder) runtime.Identifier {
|
||||
result := map[string]string{
|
||||
"name": "stripVersion",
|
||||
}
|
||||
if e != nil {
|
||||
result["encoder"] = string(e.Identifier())
|
||||
}
|
||||
identifier, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed marshaling identifier for stripVersionEncoder: %v", err)
|
||||
}
|
||||
return runtime.Identifier(identifier)
|
||||
}
|
||||
|
||||
func (c stripVersionEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
@ -54,6 +79,11 @@ func (c stripVersionEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return c.serializer.Encode(roundTrippedObj, w)
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (c stripVersionEncoder) Identifier() runtime.Identifier {
|
||||
return c.identifier
|
||||
}
|
||||
|
||||
// stripVersionNegotiatedSerializer will return stripVersionEncoder when
|
||||
// EncoderForVersion is called. See comments for stripVersionEncoder.
|
||||
type stripVersionNegotiatedSerializer struct {
|
||||
@ -69,5 +99,5 @@ func (n stripVersionNegotiatedSerializer) EncoderForVersion(encoder runtime.Enco
|
||||
panic(fmt.Sprintf("Unable to extract serializer from %#v", encoder))
|
||||
}
|
||||
versioned := n.NegotiatedSerializer.EncoderForVersion(encoder, gv)
|
||||
return stripVersionEncoder{versioned, serializer}
|
||||
return newStripVersionEncoder(versioned, serializer)
|
||||
}
|
||||
|
@ -287,6 +287,10 @@ func (e *fakeEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *fakeEncoder) Identifier() runtime.Identifier {
|
||||
return runtime.Identifier("fake")
|
||||
}
|
||||
|
||||
func gzipContent(data []byte, level int) []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
gw, err := gzip.NewWriterLevel(buf, level)
|
||||
|
@ -58,6 +58,11 @@ func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return unstructured.UnstructuredJSONScheme.Encode(obj, w)
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (dynamicCodec) Identifier() runtime.Identifier {
|
||||
return unstructured.UnstructuredJSONScheme.Identifier()
|
||||
}
|
||||
|
||||
// UnstructuredPlusDefaultContentConfig returns a rest.ContentConfig for dynamic types. It includes enough codecs to act as a "normal"
|
||||
// serializer for the rest.client with options, status and the like.
|
||||
func UnstructuredPlusDefaultContentConfig() rest.ContentConfig {
|
||||
|
@ -190,6 +190,10 @@ func (c *fakeCodec) Encode(obj runtime.Object, stream io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *fakeCodec) Identifier() runtime.Identifier {
|
||||
return runtime.Identifier("fake")
|
||||
}
|
||||
|
||||
type fakeRoundTripper struct{}
|
||||
|
||||
func (r *fakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user