【问题标题】:What is the proper way to Patch an object with controller-runtime?使用控制器运行时修补对象的正确方法是什么?
【发布时间】:2020-03-16 01:39:26
【问题描述】:

我正在尝试更新对象的 Env 字段,但我不想遍历它们以确定哪些字段已经存在并且需要更新而不是插入(如果没有必要)。我正在使用控制器运行时。

我尝试使用 ApplyPatchType 进行修补,如下所示:
r.Patch(ctx, myDeployment, client.Apply)
其中client.Apply是heremyDeployment是一个*appsv1.Deployment,我用List(...)找到然后修改了。

这失败了415 Unsupported Media Type。我认为它与需要在 YAML 中编码有关(因为类型的值是“application/apply-patch+yaml”

我这样做了(r 有一个嵌入式控制器运行时客户端):

newDeploy := dep.DeepCopy()
original := dep.DeepCopy()
// ... (changing newDeploy)
rawObj, _ := apijson.Marshal(newDeploy)
r.Patch(ctx, original, client.ConstantPatch(types.StrategicMergePatchType, rawObj))

不过,这感觉效率低下,可能有不必要的 DeepCopies,而且我觉得我在编组我的对象是不必要的。我想我可以以某种方式使用Patch 命令,类似于我使用Update 命令的方式,在这里我可以传入已修改状态的对象并获得StrategicMergePatchType(或ApplyPatchType)行为。

在我看来,如果我只想传入修改后的对象并让客户端“弄清楚”要修补什么,我想使用 client.Apply (ApplyPatchType) 行为,因为我认为 StrategicMergePatchType 只是应用差异(尽管我认为提供整个对象仍然可以是有效的差异)。任何指导表示赞赏!

【问题讨论】:

    标签: kubernetes kubernetes-apiserver


    【解决方案1】:

    现在,我得到了我正在寻找的行为,而无需使用 client.MergeFrom 手动编写合并逻辑:

    MergeFrom 创建一个补丁,该补丁使用以给定对象为基础的合并补丁策略进行补丁。

    相关代码:

    r.Patch(ctx, newDeploy, client.MergeFrom(original))

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多