K8s源码分析(6)-Resource Content 序列化

上一篇文章中我们主要介绍了对 kubernetes 世界中的不同 resource 的序列化,其中包括了 kubernetes 对于常用的不同格式 (json, yaml, protobuf) 数据的支持。以及以常见的 json 协议格式的数据做为例子,介绍了 json 序列化的核心组件 serializer.json.Serializer 对象,以及 MetaFactory 组件是如何来反序列化提取 resource 的 group, version, kind 等属性。在这里我们同样还是以 json 协议格式的数据做为例子,来继续介绍 serializer.json.Serializer 组件是如何序列化得到 resource 的 content,其中包括利用 decode 操作从请求中提取相关的 resource 对象, 以及利用 encode 操作来把相关 resource 写入到响应中去。

Resource Decode:

serializer.json.Serializer.Decode() 方法中定义了 decode 操作:

func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
  data := originalData
  if s.options.Yaml {
    altered, err := yaml.YAMLToJSON(data)
    if err != nil {
      return nil, nil, err
    }
    data = altered
  }


  actual, err := s.meta.Interpret(data)
  if err != nil {
    return nil, nil, err
  }


  if gvk != nil {
    *actual = gvkWithDefaults(*actual, *gvk)
  }


  if unk, ok := into.(*runtime.Unknown); ok && unk != nil {
    unk.Raw = originalData
    unk.ContentType = runtime.ContentTypeJSON
    unk.GetObjectKind().SetGroupVersionKind(*actual)
    return unk, actual, nil
  }


  if into != nil {
    _, isUnstructured := into.(runtime.Unstructured)
    types, _, err := s.typer.ObjectKinds(into)
    switch {
    case runtime.IsNotRegisteredError(err), isUnstructured:
      if err := caseSensitiveJSONIterator.Unmarshal(data, into); err != nil {
        return nil, actual, err
      }
      return into, actual, nil
    case err != nil:
      return nil, actual, err
    default:
      *actual = gvkWithDefaults(*actual, types[0])
    }
  }


  if len(actual.Kind) == 0 {
    return nil, actual, runtime.NewMissingKindErr(string(originalData))
  }
  if len(actual.Version) == 0 {
    return nil, actual, runtime.NewMissingVersionErr(string(originalData))
  }


  // use the target if necessary
  obj, err := runtime.UseOrCreateObject(s.typer, s.creater, *actual, into)
  if err != nil {
    return nil, actual, err
  }


  if err := caseSensitiveJSONIterator.Unmarshal(data, obj); err != nil {
    return nil, actual, err
  }


  // If the deserializer is non-strict, return successfully here.
  if !s.options.Strict {
    return obj, actual, nil
  }


  altered, err := yaml.YAMLToJSONStrict(originalData)
  if err != nil {
    return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
  }


  strictObj := obj.DeepCopyObject()
  if err := strictCaseSensitiveJSONIterator.Unmarshal(altered, strictObj); err != nil {
    return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
  }


  return obj, actual, nil
}

其中的逻辑分析流程如下:

b6d9d4cfa1109a693e12210e4bc9189e.png

Resource Encode

serializer.json.Serializer.Encode() 方法定义了 encode 操作:

func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
  if co, ok := obj.(runtime.CacheableObject); ok {
    return co.CacheEncode(s.Identifier(), s.doEncode, w)
  }
  return s.doEncode(obj, w)
}
func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
  if s.options.Yaml {
    json, err := caseSensitiveJSONIterator.Marshal(obj)
    if err != nil {
      return err
    }
    data, err := yaml.JSONToYAML(json)
    if err != nil {
      return err
    }
    _, err = w.Write(data)
    return err
  }


  if s.options.Pretty {
    data, err := caseSensitiveJSONIterator.MarshalIndent(obj, "", "  ")
    if err != nil {
      return err
    }
    _, err = w.Write(data)
    return err
  }
  encoder := json.NewEncoder(w)
  return encoder.Encode(obj)
}

其中的逻辑分析流程如下:

d646717aac2628b6a068850f707ccf5d.png

目前先我们写到这里,在下一篇文章中我们继续来介绍 kubernates resource 的序列化过程中涉及到的 codec 和 codec factory。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值