具体的学习可以先去看看官方文档 或者去https://cuetorials.com/zh/introduction/ 看看
基本定义
之后输出 cue export xx.cue
(文件名) 即可输出 可以指定只输出某个变量 使用-e 比如 cue export xx.cue -e user
这样就只会输出user这个变量 也可以指定起输出变成yaml 比如 cue export xx.cue -e user —out yaml
拆分对象
想拆分某个对象可以这样做
1 2 3 4 5 6 7 8 9
| metadata: { name: "abc" }
pod: { apiVersion: "v1", kind: "kind", "metadata": metadata, }
|
其中metadata就是引用的上面的那个metadata
基本规则验证
1 2 3 4 5 6 7 8 9 10 11 12 13
| name: string }
metadata: name: "abc" }
pod: { apiVersion: "v1", kind: "kind", "metadata": metadata, }
|
其中#后面跟的就是规则的名称 这个是定义规则的
然后某个变量想引用他的话 变量名后面加上这个规则 再加上& 符号即可
验证规则中的选填项
但是要注意 这个验证规则中的字段要在引用其的变量中都出现 如果某个规则 你可填 可不填 就使用?号来解决 比如下面这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| name: string namespace?: string }
metadata: name: "abc" }
pod: { apiVersion: "v1", kind: "kind", "metadata": metadata, }
|
其中验证规则中 namespace就是可填可不填 因为加了 ?
号
验证规则中的 默认项
如果想在验证规则中插入一个默认项, 比如这个字段我没有写, 但是他会给来个默认的 可以用 或者符号 |
其中*
号表示后面跟的默认值下面是例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| name: string namespace: string | *"default" }
metadata: name: "abc" }
pod: { apiVersion: "v1", kind: "kind", "metadata": metadata, }
|
这样就算是之后在字段中没有写metadata的namespace 他也会给你塞入一个默认值
验证规则中的列表验证
如果是列表 可以用下面的来验证
1 2 3 4 5 6
| name? : string image: string }
|
其中[…] 就是代表列表的意思
变量的使用
1 2 3 4 5 6 7 8 9 10
| param: { apiVersion: "v1", kind: "kind", }
pod : { apiVersion: param.apiVersion, kind: param.kind, "metadata": metadata, }
|
渲染cue
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
| package main
import ( "cuelang.org/go/cue" "cuelang.org/go/cue/cuecontext" "github.com/gin-gonic/gin" "k8s-cue/pkg/utils" ) type InPutPod struct { APIVersion string `json:"apiVersion"` Kind string `json:"kind"` Name string `json:"name"` }
func main() { r:=gin.New() r.POST("/", func(c *gin.Context) { pod:=&InPutPod{} err:=c.ShouldBindJSON(pod) if err != nil { c.AbortWithStatusJSON(400,gin.H{"err":err.Error()}) return } cc:=cuecontext.New() cv:=cc.CompileBytes(utils.MustLoadFile("./test.cue")) cv=cv.FillPath(cue.ParsePath("param"),cc.Encode(pod)) b,err:=cv.LookupPath(cue.ParsePath("pod")).MarshalJSON() if err != nil { c.AbortWithStatusJSON(400,gin.H{"err":err.Error()}) return }
c.Writer.Header().Add("content-type","application/json") c.Writer.Write(b)
})
r.Run(":8080")
}
|
for循环的用法
举个例子
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
| name? : string image: string }
param: { containers: [ { name: "nginx", image:"nginx1.18-alpine" } ] }
pod : { apiVersion: "v1", kind: "kind", "metadata": metadata, spec:{ if param.containers != _|_ { "containers": for _,v in param.containers{ v } ] } } }
|
cue包的引用
使用 cue mod init 可以先初始化包
1 2 3 4 5 6 7 8 9 10 11
| ├─cue.mod │ ├─pkg │ │ └─k8s.io │ │ └─schemas │ │ └─appsv1 │ └─usr |_ module.cue ├─fast ├─pkg │ └─utils └─test
|
会出现 cue.mod这个文件夹 下面有以下几个文件: pkg文件夹 user文件夹 module.cue文件
我们可以在module里面写上包名, 比如
之后 我们就可以在test里面去引用了
这是test的文件夹 下面有个version.cue 他的包名和他上一级的文件夹一样 都是test
之后 我们就可以在测试文件中引用他
当然包也可以在cue.mod文件夹下面的pkg里面写
之后他引用的格式 就不用带module.cue写的那个包名了 直接就是文件夹路径就好了