CUE语言基础入门:CUE是一门为配置而生的语言
基础入门
从这一部分开始,我们会介绍 KubeVela 是如何基于 CUE 来实现抽象和扩展的。本节将主要介绍一些 CUE 的基础知识,如果你对 KubeVela 的核心概念还不了解也没有关系,对于那些想要快速了解 CUE 并做一些实践的读者,本节也同样适用。
概述
KubeVela 将 CUE 作为应用交付核心依赖和扩展方式的原因如下::
- CUE 本身就是为大规模配置而设计。 CUE 能够感知非常复杂的配置文件,并且能够安全地更改可修改配置中成千上万个对象的值。这非常符合 KubeVela 的目标,即以可编程的方式,去定义和交付生产级别的应用程序。
- CUE 支持一流的代码生成和自动化。 CUE 原生支持与现有工具以及工作流进行集成,反观其他工具则需要自定义复杂的方案才能实现。例如,需要手动使用 Go 代码生成 OpenAPI 模式。KubeVela 也是依赖 CUE 该特性进行构建开发工具和 GUI 界面的。
- CUE 与 Go 完美集成。 KubeVela 像 Kubernetes 系统中的大多数项目一样使用 GO 进行开发。CUE 已经在 Go 中实现并提供了丰富的 API。KubeVela 以 CUE 为核心实现 Kubernetes 控制器。借助 CUE,KubeVela 可以轻松处理数据约束问题。
更多细节请查看 The Configuration Complexity Curse 以及 The Logic of CUE 两篇文章。
前提
学习 CUE 命令行
CUE 是 JSON 的超集, 我们可以像使用 JSON 一样使用 CUE,并具备以下特性:
a: 1.5
a: float
b: 1
b: int
d: [1, 2, 3]
g: {h: "abc"
}
e: string
接下来,我们以上面这个文件为例子,来学习 CUE 命令行的相关指令:
如何格式化 CUE 文件。(如果你使用 Goland 或者类似 JetBrains IDE, 可以参考该文章配置自动格式化插件 使用 Goland 设置 cuelang 的自动格式化。)
该命令不仅可以格式化 CUE 文件,还能提示错误的模型,相当好用的命令。
cue fmt first.cue
如何校验模型。除了
cue fmt
,你还可以使用cue vet
来校验模型。$ cue vet first.cue some instances are incomplete; use the -c flag to show errors or suppress this message$ cue vet first.cue -c e: incomplete value string
提示我们:这个文件里的 e 这个变量,有数据类型
string
但并没有赋值。如何计算/渲染结果。
cue eval
可以计算 CUE 文件并且渲染出最终结果。 我们看到最终结果中并不包含a: float
和b: int
,这是因为这两个变量已经被计算填充。 其中e: string
没有被明确的赋值, 故保持不变.$ cue eval first.cue a: 1.5 b: 1 d: [1, 2, 3] g: {h: "abc" } e: string
如何指定渲染的结果。例如,我们仅想知道文件中
b
的渲染结果,则可以使用该参数-e
。$ cue eval -e b first.cue 1
如何导出渲染结果。
cue export
可以导出最终渲染结果。如果一些变量没有被定义执行该命令将会报错。$ cue export first.cue e: incomplete value string
我们更新一下
first.cue
文件,给e
赋值:a: 1.5 a: float b: 1 b: int d: [1, 2, 3] g: {h: "abc" } e: string e: "abc"
然后,该命令就可以正常工作。默认情况下, 渲染结果会被格式化为 JSON 格式。
$ cue export first.cue {"a": 1.5,"b": 1,"d": [1,2,3],"g": {"h": "abc"},"e": "abc" }
如何导出 YAML 格式的渲染结果。
$ cue export first.cue --out yaml a: 1.5 b: 1 d: - 1 - 2 - 3 g:h: abc e: abc
如何导出指定变量的结果。
$ cue export -e g first.cue {"h": "abc" }
以上, 你已经学习完所有常用的 CUE 命令行指令。
学习 CUE 语言
在熟悉完常用 CUE 命令行指令后,我们来进一步学习 CUE 语言。
// float
a: 1.5// int
b: 1// string
c: "blahblahblah"// array
d: [1, 2, 3, 1, 2, 3, 1, 2, 3]// bool
e: true// struct
f: {a: 1.5b: 1d: [1, 2, 3, 1, 2, 3, 1, 2, 3]g: {h: "abc"}
}// null
j: null
如何自定义 CUE 类型?使用 #
符号来指定一些表示 CUE 类型的变量。
#abc: string
我们将上述内容保存到 second.cue
文件。 执行 cue export
不会报 #abc
是一个类型不完整的值。
$ cue export second.cue
{}
#abc: {x: inty: stringz: {a: floatb: bool}
}
自定义结构在 KubeVela 中被广泛用于模块定义(X-Definitions)和进行验证。
定义一个 CUE 模板
下面,我们开始尝试利用刚刚学习到的知识,来定义 CUE 模版。
parameter: {name: stringimage: string
}
template: {apiVersion: "apps/v1"kind: "Deployment"spec: {selector: matchLabels: {"app.oam.dev/component": parameter.name}template: {metadata: labels: {"app.oam.dev/component": parameter.name}spec: {containers: [{name: parameter.nameimage: parameter.image}]}}}
}
熟悉 Kubernetes 的你可能已经知道,这是 Kubernetes Deployment 的模板。 parameter
为模版的参数部分。
parameter:{name: "mytest"image: "nginx:v1"
}
$ cue export deployment.cue -e template --out yamlapiVersion: apps/v1
kind: Deployment
spec:selector:matchLabels:app.oam.dev/component: mytesttemplate:metadata:labels:app.oam.dev/component: mytestspec:containers:- name: mytestimage: nginx:v1
以上,你就得到了一个 Kubernetes Deployment 类型的模板。
CUE 的更多用法
设计开放的结构体和数组。如果在数组或者结构体中使用
...
,则说明该对象为开放的。数组对象
[...string]
,说明该对象可以容纳多个字符串元素。 如果不添加...
, 该对象[string]
说明数组只能容纳一个类型为string
的元素。如下所示的结构体说明可以包含未知字段。
{abc: string ... }
使用运算符
|
来表示两种类型的值。如下所示,变量a
表示类型可以是字符串或者整数类型。
a: string | int
- 使用符号
*
定义变量的默认值。通常它与符号|
配合使用, 代表某种类型的默认值。如下所示,变量a
类型为int
,默认值为1
。
a: *1 | int
- 让一些变量可被选填。 某些情况下,一些变量不一定被使用,这些变量就是可选变量,我们可以使用
?:
定义此类变量。 如下所示,a
是可选变量, 自定义#my
对象中x
和z
为可选变量, 而y
为必填字段。
a ?: int#my: {
x ?: string
y : int
z ?:float
}
选填变量可以被跳过,这经常和条件判断逻辑一起使用。 具体来说,如果某些字段不存在,则 CUE 语法为 if _variable_!= _ | _
,如下所示:
parameter: {name: stringimage: stringconfig?: [...#Config]
}
output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageif parameter.config != _|_ {config: parameter.config}}]}...
}
- 使用运算符
&
来运算两个变量。
a: *1 | int
b: 3
c: a & b
保存上述内容到 third.cue
文件。
你可以使用 cue eval
来验证结果:
$ cue eval third.cue
a: 1
b: 3
c: 3
- 需要执行条件判断。当你执行一些级联操作时,不同的值会影响不同的结果,条件判断就非常有用。 因此,你可以在模版中执行
if..else
的逻辑。
price: number
feel: *"good" | string
// Feel bad if price is too high
if price > 100 {feel: "bad"
}
price: 200
保存上述内容到 fourth.cue
文件。
你可以使用 cue eval
来验证结果:
$ cue eval fourth.cue
price: 200
feel: "bad"
另一个示例是将布尔类型作为参数。
parameter: {name: stringimage: stringuseENV: bool
}
output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageif parameter.useENV == true {env: [{name: "my-env", value: "my-value"}]}}]}...
}
使用 For 循环。 我们为了避免减少重复代码,常常使用 For 循环。
映射遍历。
parameter: {name: stringimage: stringenv: [string]: string } output: {spec: {containers: [{name: parameter.nameimage: parameter.imageenv: [for k, v in parameter.env {name: kvalue: v},]}]} }
类型遍历。
#a: {"hello": "Barcelona""nihao": "Shanghai" }for k, v in #a {"\(k)": {nameLen: len(v)value: v} }
切片遍历。
parameter: {name: stringimage: stringenv: [...{name:string,value:string}] } output: {...spec: {containers: [{name: parameter.nameimage: parameter.imageenv: [for _, v in parameter.env {name: v.namevalue: v.value},]}]} }
- 循环内使用条件判断
parameter: [ {name: "empty" }, {name: "xx1" }, ]dataFrom: [ for _, v in parameter { if v.name != "empty" {name: v.name } }]
结果是:
cue eval ../blog/a.cue -e dataFrom [{}, {name: "xx1" }]
- 将条件判断作为循环的条件
parameter: [ {name: "empty" }, {name: "xx1" }, ]
dataFrom: [ for _, v in parameter if v.name != “empty” { name: v.name }]
结果是:
cue eval …/blog/a.cue -e dataFrom [{ name: “xx1” }]
另外,可以使用 "\( _my-statement_ )"
进行字符串内部计算,比如上面类型循环示例中,获取值的长度等等操作。
导入 CUE 内部包
CUE 有很多 internal packages 可以被 KubeVela 使用,这样可以满足更多的开发需求。
比如,使用 strings.Join
方法将字符串数组拼接成字符串。
import ("strings")parameter: {outputs: [{ip: "1.1.1.1", hostname: "xxx.com"}, {ip: "2.2.2.2", hostname: "yyy.com"}]
}
output: {spec: {if len(parameter.outputs) > 0 {_x: [ for _, v in parameter.outputs {"\(v.ip) \(v.hostname)"}]message: "Visiting URL: " + strings.Join(_x, "")}}
}
至此,你已经学会了基础的 CUE 知识,如果你还想了解更多的 CUE 实践细节,可以参考其官方文档。
在本部分接下来的章节里,我们会开始介绍 KubeVela 如何使用 CUE 像胶水一样衔接不同的资源,请确保你对 KubeVela 的核心概念有所了解。
http://static.kubevela.net/zh/docs/platform-engineers/cue/basic
CUE语言基础入门:CUE是一门为配置而生的语言相关推荐
- R语言基础入门(全)
R 是门语言,也是个环境.个人认为R有点像matlab. R自带多种统计学及数字分析功能.R的功能也可以通过安装包(Packages,用户撰写的功能)增强,个人感觉这个就是插件.因为S的血缘,R比其他 ...
- c语言用if语句abc输出最大值,C语言基础入门选择结构-if语句(78页)-原创力文档...
C语言基础入门选择结构-if语句_电脑基础知识_IT/计算机_专业资料.第9单元选择结构-if语句<程序设计基础>北京八维研修学院第1节选择结构导入?... <程序设计基础> ...
- C语言基础入门学习笔记
前言 我是一个初中生,过完暑假就是一个高一的学生了.在这个暑假里,我学习了韦东山老师和唐佐林老师的课程,所以我写下这个笔记来记录自己的成长历程. C语言基础入门学习笔记 格式 #include < ...
- 【学习笔记】山东大学生物信息学——Perl 语言基础入门+高级
文章目录 8.3 Perl 语言基础入门 8.3.1 第一个 Perl 8.3.2 Perl 的基本规则 8.3.3 字符串常用函数 8.3.4 数组常用函数 8.4 Perl 语言基础高级 8.4. ...
- php语言入门,php语言基础入门
php语言基础入门 导语:PHP语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域.下面是PHP语言基础人们知识,欢迎参考! 1. 代码嵌在内 2.输出函数ech ...
- r语言折线图_R语言基础入门视频教程——语法篇(完结)
这个视频分了2个阶段录制的,第1阶段有10章的内容,在文章:生物专业学生0基础入门R语言语法视频教程,就有说明,后面把最后2章补录完成啦,也算是一个结局啦.下面是目录: 第01章:R语言简介(免费) ...
- Lua语言基础入门 (Lua学习一)
Lua语言快速入门 这篇博客主要是简单的讲解一下Lua的基础知识,涉及的东西不是很深,提供一些学习的思路,对具体的技术不展开介绍,网上资料很多写的都比我好,仅仅为了使用Lua,而不是做基于Lua的项目 ...
- c语言输入r1 r2垫片的面积,C语言基础入门设计
实验一 实验 1 一. 实验目的 C 语言程序设计入门篇 简单的 C 程序设计 1.熟悉 VC++语言上机环境及上机操作过程. 2.了解如何编辑.编译.连接和运行一个 C 程序. 3.掌握 C 语言中 ...
- C语言基础入门 - 第一章 - 从入门到入土
1.1 C语言概述 ----------------------------------------------------------------------------------------- ...
最新文章
- linux下如何安装rzsz
- Nginx加入linux系统服务
- Java中的访问者设计模式–示例教程
- 微型计算机上的南桥芯片功能,微型计算机及接口技术2012年1月真题试题(04732)...
- ubuntu-kylin16.04搭建lamp环境。
- js数组依据下标删除元素
- 基本sql语句--增删改查
- 老李分享:Web Services 组件
- 自主创新生态圈再扩大,深度科技与金格科技完成产品兼容性认证
- es6初识笔记(参看阮一峰ECAMscript6入门)
- html调色板快捷键,在线网页调色板
- javacv 人脸追踪_基于JavaCV的人脸识别程序
- 多端开发之uniapp开发app
- Lambda方法引用
- 循环、推导式、多重循环
- 计算机软件定时运行,win10系统设置定时运行指定软件的详细方案
- mapbox-gl:图层过滤显示
- 祝福语大全 计算机,【一到十的祝福语】 从一到十的祝福语_一到十祝福语大全_东城教研...
- Collection概述与基本使用
- win10系统设置开机网络自动连接的方法