前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8s源码分析(6)-Resource Content 序列化

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

作者头像
TA码字
发布2021-10-08 15:22:19
4070
发布2021-10-08 15:22:19
举报
文章被收录于专栏:TA码字

上一篇文章中我们主要介绍了对 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 操作:

代码语言:javascript
复制
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
}

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

Resource Encode

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

代码语言:javascript
复制
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)
}

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TA码字 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档