cue语法

安装 cue:

go get -u cuelang.org/go/cmd/cue

常用命令

语法检查:

cue vet mpserver.cue

格式化:

cue fmt mpserver.cue

输出:

cue export mpserver.cue

输出指定参数:

cue export mpserver.cue  -e output

指定参数输出成YAML文件:

cue export mpserver.cue  -e output --out yaml

yaml 文件转换为 cue 文件:

cue import deployment.yaml

详细语法说明

导入golang包

cuelang 可以导入 golang 的包,比如可以导入 json包来处理 json 文件,导入strconv包做字符串和整型转换:

import (
"strconv"
"encoding/json"
)

test: {
name: strconv.FormatInt(parameter.value, 10)
test: json.Marshal(testvalue)
}

testvalue = {"value": 10}

parameter: {
name: string
value: int
}

# 设置值
parameter: {
name: "test"
value: 10
}

结果output:

$ cue export cue-test.cue
{
"test": {
"name": "10",
"test": "{\"value\":10}"
},
"parameter": {
"name": "test",
"value": 10
}
}

字符串拼接

cuelang 可以通过 \(变量) 将变量和字符串拼接:

import (
"strconv"
"encoding/json"
)

test: {
name: strconv.FormatInt(parameter.value, 10)
test: "example: \(json.Marshal(testvalue))"
}

testvalue = {"value": 10}

parameter: {
name: string
value: int
}

parameter: {
name: "test"
value: 10
}

结果output:

$ cue export cue-test.cue
{
"test": {
"name": "10",
"test": "example: {\"value\":10}"
},
"parameter": {
"name": "test",
"value": 10
}
}

参数定义为可选参考

cuelang 中 ? 表示参数可选:

import (
"encoding/json"
)

test: {
name: parameter.name
value: json.Marshal(testvalue)
}

testvalue = {"value": 10}

parameter: {
name: string
value?: int
}

parameter: {
name: "test"
}

结果output:

$ cue export cue-test.cue
{
"test": {
"name": "test",
"value": "{\"value\":10}"
},
"parameter": {
"name": "test"
}
}

设置默认值

cuelang 用*表示默认值:

test: {
name: *parameter.name | "test" //缺失就会用默认值代替
value: *parameter.value | 0
}

parameter: {
name: string
value?: int
}

parameter: {
name: "new"
}

结果output:

$ cue export cue-test.cue
{
"test": {
"name": "new",
"value": 0
},
"parameter": {
"name": "new"
}
}

条件判断

cue 的条件判断也是用 if,语法和 golang一致,不过表示空对象用_|_表示:

test: {
name: parameter["name"]
if parameter.value != _|_ {
value: parameter.value
}

}

parameter: {
name: string
value?: int
}

parameter: {
name: "test"
}

结果output:

$ cue export cue-test.cue
{
"test": {
"name": "new"
},
"parameter": {
"name": "new"
}
}

逻辑比较运算符

cuelang 提供了逻辑运算符,比如 |&,用法如下:

test: {
name: parameter["name"]
value: parameter["value"]
}

parameter: {
name: string
value?: *0 | >=0 & < 10
}

parameter: {
name: "test"
value: 11
}

结果output:

$ cue export cue-test.cue
parameter.value: empty disjunction: conflicting values 0 and 11:
.\cue-test.cue:8:14
.\cue-test.cue:13:12
test.value: empty disjunction: conflicting values 0 and 11:
.\cue-test.cue:8:14
.\cue-test.cue:13:12
parameter.value: empty disjunction: invalid value 11 (out of bound <10):
.\cue-test.cue:8:24
.\cue-test.cue:13:12
test.value: empty disjunction: invalid value 11 (out of bound <10):
.\cue-test.cue:8:24
.\cue-test.cue:13:12

将 parameter 的值 value 改为 5:

$ cue export cue-test.cue
{
"test": {
"name": "test",
"value": 5
},
"parameter": {
"name": "test",
"value": 5
}
}

循环语句 for 和 数组

cuelang 里面的数组:

test: {
name: parameter["name"]
value: parameter["value"]
}

parameter: {
name: [...string]
value?: [... >=0 & < 10 & int]
}

parameter: {
name: ["test1","test2"]
value: [5]
}

output结果输出:

$ cue export cue-test.cue
{
"test": {
"name": [
"test1",
"test2"
],
"value": [
5
]
},
"parameter": {
"name": [
"test1",
"test2"
],
"value": [
5
]
}
}

循环:

test: {
key: [
for k,v in parameter["name"]{
name: v
}
]
}

parameter: {
name: [...string]
}

parameter: {
name: ["test1","test2"]
}

output 结果输出:

$ cue export cue-test.cue
{
"test": {
"key": [
{
"name": "test1"
},
{
"name": "test2"
}
]
},
"parameter": {
"name": [
"test1",
"test2"
]
}
}

vela 里面的 cuelang 模板

后面我们通过vela的模板文件进行 cue 语法学习:

output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
"app": context.name
}

template: {
metadata: labels: {
"app.oam.dev/component": context.name
"app": context.name
}

spec: {
containers: [{
name: context.name
image: parameter.image

if parameter["cmd"] != _|_ {
command: parameter.cmd
}

if parameter["env"] != _|_ {
env: parameter.env
}

if context["config"] != _|_ {
env: context.config
}

ports: [{
containerPort: parameter.port
}]

if parameter["cpu"] != _|_ {
resources: {
limits:
cpu: parameter.cpu
memory: parameter.memory
requests:
cpu: parameter.cpu
memory: parameter.memory
}
}

}]
}
}
}
}

parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string

// +usage=Commands to run in the container
cmd?: [...string]

// +usage=Which port do you want customer traffic sent to
// +short=p
port: *80 | int
// +usage=Define arguments by using environment variables
env?: [...{
// +usage=Environment variable name
name: string
// +usage=The value of the environment variable
value?: string
// +usage=Specifies a source the value of this var should come from
valueFrom?: {
// +usage=Selects a key of a secret in the pod's namespace
secretKeyRef: {
// +usage=The name of the secret in the pod's namespace to select from
name: string
// +usage=The key of the secret to select from. Must be a valid secret key
key: string
}
}
}]
// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
memory?: string
}

parameter: {
image: "test"
cmd: ["nginx"]
}

context: {
name: "test"
}
shikanon wechat
欢迎您扫一扫,订阅我滴↑↑↑的微信公众号!