HAOJX

clientset中patch操作:jsonpatch

字数统计: 749阅读时长: 3 min
2021/11/17 Share

JSONPatch的详细说明请参考文档:http://jsonpatch.com/。JSONPatch 主要有三种操作方式:add,replace,remove。以下会以代码示例说明这三种操作在Client-go对应的代码示例来说明怎样操作K8s 的资源。

使用JSONPatch,如果Patch中带有斜杠“/”和 (~)这两个字符,不能直接传入这两个字符,需要你输入的时候就人工转换下,/转换成~1,~转换成~0。以新增labels为例,如我要新增一个”test1/test2”:”test3”的labels,可以把要传入的数据修改为”test1~1test2”:”test3”即可。

add

使用JSONPatch的方式新增一个标签,其提交的数据格式必须是[{ "op": "add/remove/replace", "path": "xxx", "value": "xxx" }] 这样的。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package main

import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/json"
"kube-base3/lib/kubeConfig"
"log"
)

type JsonPatch struct {
Op string `json:"op"`
Path string `json:"path"`
Value interface{} `json:"value,omitempty"`
}

type JsonPatchList []*JsonPatch

func AddJsonPatch(j ...*JsonPatch) JsonPatchList {
list := make(JsonPatchList, len(j))

for i, v := range j {
list[i] = v
}
return list
}

func main() {
ctx := context.Background()
client := kubeConfig.InitClient()

mydep, err := client.AppsV1().Deployments("default").Get(ctx, "myapp-deploy", metav1.GetOptions{})
if err != nil {
log.Fatal(err)
}

list := AddJsonPatch(&JsonPatch{
Op: "add",
Path: "/spec/template/spec/containers/0",
Value: map[string]interface{}{
"name": "redis",
"image": "redis:5-alpine",
},
})
b, err := json.Marshal(list)
fmt.Println(string(b))
if err != nil {
log.Fatal(err)
}
_, err = client.AppsV1().Deployments(mydep.Namespace).Patch(ctx, mydep.Name, types.JSONPatchType, b, metav1.PatchOptions{})
if err != nil {
log.Fatal(err)
}
fmt.Println("patch success")
}

使用add有个需要注意的地方就是,当你的Path是使用的/metadata/labels而不是/metadata/labels/labelkey的时候,那你这个add操作实际是对整个labels进行替换,而不是新增,一定要注意避免踩坑。 如果要操作某个key 这个key要写编号 一般是编号从0开始 比如path:”/spec/template/spec/containers/0” PS:如果不喜欢使用上面struct的方式组成数据,可以使用如下的方式 labelsPatch := fmt.Sprintf([{“op”:”add”,”path”:”/metadata/labels/%s”,”value”:”%s” }], labelkey, labelvalue) 直接代替上面示例中的patchData

这里还有个要注意的地方就是:

当这个path里面的路径上没有值的时候 这个时候增加是会报错的 比如说 path: “/metadata/annotations/version” value:”v1.0” 这个时候 如果这个annotation没有值 是空的话 这个会报错的 所以添加的路径上一定要存在才能添加值 没有的话 就用这种形式path: “/metadata/annotations” value: map[string]interface{}{ “version”:””v1.0} 这样就可以了 记得上面的path写annotation的话 不要多写一个/ 路径不要写错了

remove

要删除一个标签的话,代码和增加区别不大,唯一的区别就是提交的数据要由键值对修改成 没有value类型的 op和path 2个就够了

1
2
3
4
5
6
7
8
9
10
....
list := AddJsonPatch(&JsonPatch{
Op: "remove",
Path: "/spec/template/spec/containers/0",
//Value: map[string]interface{}{
// "name": "redis",
// "image": "redis:5-alpine",
//},
})
....

类似于这种

CATALOG
  1. 1. add
  2. 2. remove