kubernetes Content-Type for RestClient Patch()被Body()方法覆盖

ewm0tg9j  于 10个月前  发布在  Kubernetes
关注(0)|答案(3)|浏览(100)

发生了什么?
我正在编写一个使用client-go rest客户端来修补CRD的方法:

  1. err := c.restClient.
  2. Patch(types.MergePatchType).
  3. Resource(MySuperAwesomeResource).
  4. SubResource("status").
  5. Name(name).
  6. Body(superAwesomeResourceObject).
  7. Do(ctx).
  8. Into(result)

然后惊讶地收到一个错误:

  1. the body of the request was in an unknown format - accepted media types include: application/json-patch+json, application/merge-patch+json, application/apply-patch+yaml

你期望会发生什么?

由于我通过 Patch(types.MergePatchType) 设置了Content-Type,因此补丁不应该因为Content-Type不正确而失败。

我们如何尽可能精确地重现它?

使用client-go rest客户端,尝试通过将runtime.Object传递给 Body() 方法来修补资源。

我们需要了解其他信息吗?

以下是我所认为的情况:
Patch() 方法设置了Content-Type头。
但是,将k8s运行时对象传递给 Body() 会用 ClientContentConfig 中设置的任何Content-Type覆盖该头(如果且仅当传递的对象是k8s运行时对象)。这默认为 application/json ,我认为对于不是 Patch() 的HTTP方法是正确的。
如果将 Body() 对那个头的设置限制在 PATCH 动词上:

  1. if r.verb != "PATCH" {
  2. r.SetHeader("Content-Type", r.c.content.ContentType)
  3. }

那么事情就会正常工作。
还可以在 Body() 之后调用 SetHeader :

  1. err := c.restClient.
  2. Patch(types.MergePatchType).
  3. Resource(MySuperAwesomeResource).
  4. SubResource("status").
  5. Name(name).
  6. Body(superAwesomeResourceObject).
  7. SetHeader("Content-Type", string(types.MergePatchType)).
  8. Do(ctx).
  9. Into(result)

然后事情就会正常工作。
我不知道我在这里做错了什么,但这感觉更像是bug而不是操作员错误?

Kubernetes版本

  1. $ kubectl version
  2. Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3", GitCommit:"25b4e43193bcda6c7328a6d147b1fb73a33f1598", GitTreeState:"clean", BuildDate:"2023-06-14T09:53:42Z", GoVersion:"go1.20.5", Compiler:"gc", Platform:"linux/amd64"}
  3. Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3", GitCommit:"25b4e43193bcda6c7328a6d147b1fb73a33f1598", GitTreeState:"clean", BuildDate:"2023-06-14T09:53:42Z", GoVersion:"go1.20.5", Compiler:"gc", Platform:"linux/amd64"}
  4. Kustomize Version: v5.0.1
  5. Server Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3", GitCommit:"25b4e43193bcda6c7328a6d147b1fb73a33f1598", GitTreeState:"clean", BuildDate:"2023-06-15T00:36:28Z", GoVersion:"go1.20.5", Compiler:"gc", Platform:"linux/amd64"}```
  6. </details>
  7. ### Cloud provider
  8. <details>
  9. self
  10. </details>
  11. ### OS version
  12. <details>
  13. ```console
  14. # On Linux:
  15. $ cat /etc/os-release
  16. # paste output here
  17. $ uname -a
  18. # paste output here
  19. # On Windows:
  20. C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
  21. # paste output here

安装工具

容器运行时(CRI)和版本(如适用)

相关插件(CNI,CSI,...)和版本(如适用)

i34xakig

i34xakig1#

/sig api-machinery

kxe2p93d

kxe2p93d2#

我同意这至少是令人惊讶的。我在#124059(评论)中运行了相同的操作,并应用了相同的解决方法。如果Body只在尚未设置content-type头时才设置它,那么是否存在任何合法的使用场景会被破坏?假设有人调用Patch()或SetHeader("Content-Type", "foo"),那么这是有意为之的。

wlsrxk51

wlsrxk513#

/triage accepted

相关问题