美文网首页
controller-runtime patch

controller-runtime patch

作者: allenhaozi | 来源:发表于2020-12-27 22:04 被阅读0次

controller-runtime patch

Patch
github

// Writer knows how to create, delete, and update Kubernetes objects.
type Writer interface {
    // Create saves the object obj in the Kubernetes cluster.
    Create(ctx context.Context, obj runtime.Object, opts ...CreateOption) error

    // Delete deletes the given obj from Kubernetes cluster.
    Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOption) error

    // Update updates the given obj in the Kubernetes cluster. obj must be a
    // struct pointer so that obj can be updated with the content returned by the Server.
    Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error

    // Patch patches the given obj in the Kubernetes cluster. obj must be a
    // struct pointer so that obj can be updated with the content returned by the Server.
    Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error

    // DeleteAllOf deletes all objects of the given type matching the given options.
    DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...DeleteAllOfOption) error
}

Patch接口
主要三个参数

1. obj

2. patch

// Patch is a patch that can be applied to a Kubernetes object.
type Patch interface {
    // Type is the PatchType of the patch.
    Type() types.PatchType
    // Data is the raw data representing the patch.
    Data(obj runtime.Object) ([]byte, error)
}

3. opts


假设我们调用时候

r.Patch(ctx, desired, client.MergeFrom(obj), ao...)

client.MergeFrom 是一个实现了 上面Patch接口结构体mergeFromPatch
结构体如下
这里的一个核心函数是 CreateMergePatch

// MergeFrom creates a Patch that patches using the merge-patch strategy with the given object as base.
func MergeFrom(obj runtime.Object) Patch {
    return &mergeFromPatch{from: obj}
}

type mergeFromPatch struct {
    from runtime.Object
    opts MergeFromOptions
}

// Type implements patch.
func (s *mergeFromPatch) Type() types.PatchType {
    return types.MergePatchType
}

// Data implements Patch.
func (s *mergeFromPatch) Data(obj runtime.Object) ([]byte, error) {
    originalJSON, err := json.Marshal(s.from)
    if err != nil {
        return nil, err
    }

    modifiedJSON, err := json.Marshal(obj)
    if err != nil {
        return nil, err
    }

    data, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
    if err != nil {
        return nil, err
    }

    if s.opts.OptimisticLock {
        dataMap := map[string]interface{}{}
        if err := json.Unmarshal(data, &dataMap); err != nil {
            return nil, err
        }
        fromMeta, ok := s.from.(metav1.Object)
        if !ok {
            return nil, fmt.Errorf("cannot use OptimisticLock, from object %q is not a valid metav1.Object", s.from)
        }
        resourceVersion := fromMeta.GetResourceVersion()
        if len(resourceVersion) == 0 {
            return nil, fmt.Errorf("cannot use OptimisticLock, from object %q does not have any resource version we can use", s.from)
        }
        u := &unstructured.Unstructured{Object: dataMap}
        u.SetResourceVersion(resourceVersion)
        data, err = json.Marshal(u)
        if err != nil {
            return nil, err
        }
    }

    return data, nil
}

然后我们再看一下 client.Patch函数的实现

// Patch implements client.Client
func (c *typedClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
    o, err := c.cache.getObjMeta(obj)
    if err != nil {
        return err
    }

    data, err := patch.Data(obj)
    if err != nil {
        return err
    }

    patchOpts := &PatchOptions{}
    return o.Patch(patch.Type()).
        NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
        Resource(o.resource()).
        Name(o.GetName()).
        VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec).
        Body(data).
        Do(ctx).
        Into(obj)
}

r.Patch(ctx, desired, client.MergeFrom(current), ao...)
回看我们的调用
在client.Patch的实现中

  • client.MergeFrom(obj) 返回一个 mergeFromPatch 的结构体并给其from赋值
  • 然后在client.Patch中调用了这个结构体的Data()方法, 并将desired传入
  • 关键的地方来了 这里核心是使用 jsonpatch.CreateMergePatch
    • current 作为 originalJSON
    • desired 作为 modifiedJSON
      合并做merge

相关文章

网友评论

      本文标题:controller-runtime patch

      本文链接:https://www.haomeiwen.com/subject/uzdanktx.html