HAOJX

cue基本语法

字数统计: 914阅读时长: 4 min
2022/06/14 Share

具体的学习可以先去看看官方文档 或者去https://cuetorials.com/zh/introduction/ 看看

基本定义

1
2
3
user: {
name: "test"
}

之后输出 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
#metadata:{
name: string
}

metadata: #metadata & {
name: "abc"
}

pod: {
apiVersion: "v1",
kind: "kind",
"metadata": metadata,
}

其中#后面跟的就是规则的名称 这个是定义规则的

然后某个变量想引用他的话 变量名后面加上这个规则 再加上& 符号即可

验证规则中的选填项

但是要注意 这个验证规则中的字段要在引用其的变量中都出现 如果某个规则 你可填 可不填 就使用?号来解决 比如下面这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#metadata:{
name: string
namespace?: string
}

metadata: #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
#metadata:{
name: string
namespace: string | *"default"
}

metadata: #metadata & {
name: "abc"
}

pod: {
apiVersion: "v1",
kind: "kind",
"metadata": metadata,
}

这样就算是之后在字段中没有写metadata的namespace 他也会给你塞入一个默认值

验证规则中的列表验证

如果是列表 可以用下面的来验证

1
2
3
4
5
6
#container :{
name? : string
image: string
}

#containers : [...#container]

其中[…] 就是代表列表的意思

变量的使用

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
#container :{
name? : string
image: string
}

#containers : [...#container]

param: {
containers: [
{
name: "nginx",
image:"nginx1.18-alpine"
}
]
}

pod : {
apiVersion: "v1",
kind: "kind",
"metadata": metadata,
spec:{
if param.containers != _|_ {
"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里面写上包名, 比如

1
module: ""

之后 我们就可以在test里面去引用了

这是test的文件夹 下面有个version.cue 他的包名和他上一级的文件夹一样 都是test

之后 我们就可以在测试文件中引用他

当然包也可以在cue.mod文件夹下面的pkg里面写

之后他引用的格式 就不用带module.cue写的那个包名了 直接就是文件夹路径就好了

CATALOG
  1. 1. 基本定义
    1. 1.1. 拆分对象
  2. 2. 基本规则验证
    1. 2.1. 验证规则中的选填项
    2. 2.2. 验证规则中的 默认项
    3. 2.3. 验证规则中的列表验证
  3. 3. 变量的使用
  4. 4. 渲染cue
  5. 5. for循环的用法
  6. 6. cue包的引用