CUE is an open source data constraint language designed to handle configurations, structures, data and execute them. Most people start using CUE because they want to do data validation and generate configurations. Then they go on to use CUE for data templates, runtime input validation, code generation, scripting, pipline, and more. First you need to understand that CUE is not a programming language in the usual sense, it is a Turing non-complete programming language.
Unlike JSONNET, CUE does not support custom functions, but supports external schema based on typed feature structure, and supports type and data fusion through explicit unification and separation operations. CUE does not support custom functions, supports external schema based on typed feature structure, and supports type and data fusion through explicit unification and separation operations, but such settings and external type derivation also increase the difficulty of understanding and writing complexity.
The CUE project is written entirely in Golang, and relies on Golang to allow “import” of the necessary capabilities provided by CUE to help users write common functions such as encoding, strings, math, and other configurations. We can say that CUE is both a JSON-based template language, but also comes with a lot of Configuration Language thinking, providing a good sample of both its language design ideas, and the engineering approach based on the ability to introduce mature high-level programming languages are worth studying in depth.
Installation
Install CUE via official binary
The installer supports multiple operating systems, including Linux, Window, and macOS, and can be downloaded from the official CUE website https://cuelang.org/releases.
Install using homebrew
Alternatively, CUE is installed on MacOS and Linux via brew.
|
|
Installation via source code
First you need to ensure that Go 1.16 or higher is installed, then execute the following command to install it.
|
|
Once the installation is complete, you can execute the cue
command.
CUE Command Line
CUE is a superset of JSON, and we can use CUE as JSON with the following features.
- C-style comments.
- field names can be enclosed in double quotes, but no special characters are allowed in field names.
- Optional field endings with or without commas.
- Comma at the end of the last element in an array is allowed.
- Outer curly brackets optional.
Please first copy the following information and save it as a first.cue
file.
Next, let’s use the above file as an example to learn the commands on the CUE command line.
-
How to format a CUE file. The following command not only formats the CUE file, but also prompts for the wrong model, quite a good command to use.
1
cue fmt first.cue
-
How do I calibrate the model? In addition to
cue fmt
, you can also usecue vet
to verify the model.Hint: The variable e in this file has the data type
string
but is not assigned a value. -
How to calculate/render the result.
cue eval
computes the CUE file and renders the final result. We see that the final result does not containa: float
andb: int
, because these two variables are already computationally populated. Thee: string
is not explicitly assigned, so it remains unchanged. -
How to specify the result of the rendering. For example, if we only want to know the rendering result of
b
in the file, we can use this parameter-e
. -
How to export the rendering result.
cue export
exports the final rendering results. If some variables are not defined executing this command will give an error.Let’s update the
first.cue
file and assign a value toe
.Then, the command works properly. By default, the rendered results are formatted as JSON.
-
How to export rendered results in YAML format.
-
How to export the result of the specified variable.
Above, you have learned all the common CUE command line commands.
Data Types
After familiarizing yourself with the common CUE command line instructions, let’s learn more about the CUE language.
Let’s start by understanding the data types of CUE. The following are its basic data types.
How do I customize the CUE type? Use the #
symbol to specify some variables that indicate the CUE type.
|
|
We save the above to a second.cue
file. Executing cue export
does not throw an exception: #abc
is an incomplete type value.
You can also define more complex custom structures, such as:
CUE Templates
Next, let’s start trying to define the CUE template using what we just learned.
-
Define the structure variable
parameter
.Save the above variables to the file
deployment.cue
. -
Define more complex structural variables
template
while referencing the variableparameter
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
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.name image: parameter.image }] }}} }
As you may already know if you are familiar with Kubernetes, this is the template for Kubernetes Deployment.
parameter
is the parameters section of the template.Add the above to the file
deployment.cue
. -
Then, we complete the variable assignment by updating the following.
-
Finally, the rendered results are exported in YAML format.
Above, you get a template of the Kubernetes Deployment type.
Other Uses
-
Design open structures and arrays. If
...
is used in an array or structure, the object is open. ` , then the object is open.-
An array object
[... .string]
, indicates that the object can hold multiple string elements. If you do not add...
, the object[string]
indicates that the array can hold only one element of typestring
. -
The structure shown below illustrates that it can contain unknown fields.
-
-
Use the operator
|
to represent two types of values. As shown below, the variablea
indicates that the type can be either a string or an integer type.1
a: string | int
-
Use the symbol
*
to define the default value of a variable. It is usually used in conjunction with the symbol|
to represent the default value of a certain type. As shown below, the variablea
is of typeint
and has a default value of1
.1
a: *1 | int
-
Make some variables optional. In some cases, variables that are not necessarily used are optional variables, and we can use
? :
to define such variables. As shown below,a
is an optional variable,x
andz
are optional in the custom#my
object, andy
is a required field.Optional variables can be skipped, which is often used in conjunction with conditional judgment logic. Specifically, if some field does not exist, the CUE syntax is
if _variable_! = _ | _
, as follows. -
Use the operator
&
to operate on two variables.Save the above to the
third.cue
file.You can use
cue eval
to verify the results. -
Need to perform conditional judgments. Conditional judgments are very useful when you perform some cascading operations where different values affect different results. Therefore, you can execute
if..else
logic in your templates.Save the above to a
fourth.cue
file.You can use
cue eval
to verify the results.Another example is to include a boolean type as a parameter.
-
Use a For loop. We often use For loops to avoid duplicating code.
-
Mapping traversal.
-
Type traversal.
-
Slicing traversal.
-
Alternatively, you can use "\( _my-statement_ )"
to perform internal string calculations, such as getting the length of a value in the type loop example above, and so on.
Importing packages
For example, use the strings.Join
method to stitch an array of strings into a string.
|
|
You can import kubernetes packages in the CUE template via kube/<apiVersion>
, just as you would with CUE internal packages.
For example, Deployment
can be used like this.
Service
can be used like this (without importing packages using aliases).
Even installed CRD’s can be imported and used.