溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是CUE

發(fā)布時間:2021-10-11 17:20:50 來源:億速云 閱讀:332 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“什么是CUE”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

什么是CUE

C(Configure:配置) , U(Unify:統(tǒng)一) , E(Execute:執(zhí)行) 。

CUE是一種開源的數(shù)據(jù)約束語言,旨在簡化涉及定義和使用數(shù)據(jù)的任務。

它是JSON的超集,允許熟悉JSON的用戶快速上手。

換言之,他和JSON、YAML 等類似,但是比他們的功能強大,可以和 JSON、YAML 等工具對比著來理解。

CUE 可以用來做什么

我們可以用CUE :

  • 定義一個詳細的驗證模式

  • 減少數(shù)據(jù)中的模版

  • 從代碼中提取模式

  • 產(chǎn)生類型定義和驗證代碼

  • 以一種有原則的方式合并JSON

  • 定義和運行聲明性腳本

How

CUE合并了模式和數(shù)據(jù)的概念。同一個CUE定義可以同時用于驗證數(shù)據(jù)和作為模板來減少模板。模式定義通過細粒度的值定義和缺省值得到了豐富。同時,通過刪除這些詳細定義所隱含的值,可以簡化數(shù)據(jù)。這兩個概念的合并使得許多任務能夠以一種原則性的方式被處理。

約束提供了一個簡單的、定義明確的、但功能強大的、替代繼承的方法,而繼承是配置語言中常見的復雜性來源。

CUE腳本

CUE腳本層定義了聲明性的腳本,用CUE表達,在數(shù)據(jù)之上。這解決了三個問題:解決了CUE定義的封閉性(我們說CUE是密封的),提供了一個簡單的方法來分享使用數(shù)據(jù)的通用腳本和工作流程,并讓CUE知道如何使用數(shù)據(jù)來優(yōu)化驗證。

有很多工具可以解釋數(shù)據(jù)或者為特定領域使用專門的語言(Kustomize, Ksonnet)。這在一個層面上解決了處理數(shù)據(jù)的問題,但它解決的問題在工作流程中整合其他系統(tǒng)時可能會在更高的層面上重復出現(xiàn)。CUE腳本是通用的,允許用戶定義任何工作流程。

安裝

如果是 Mac 環(huán)境 ,執(zhí)行下面的命令安裝:

brew install cuelang/tap/cue

其他環(huán)境通過 golang 安裝(當然 mac 也是可以的)

# go 1.16 之前
GO111MODULE=on go get cuelang.org/go/cmd/cue

# go 1.16 之后
go install cuelang.org/go/cmd/cue@latest

詳細可參考 安裝文檔

安裝完之后可以通過命令行執(zhí)行 cue --help 查看基本的幫助文檔。

cue --help
cue evaluates CUE files, an extension of JSON, and sends them
to user-defined commands for processing.

Commands are defined in CUE as follows:

	import "tool/exec"
	command: deploy: {
		exec.Run
		cmd:   "kubectl"
		args:  [ "-f", "deploy" ]
		in:    json.Encode(userValue) // encode the emitted configuration.
	}

cue can also combine the results of http or grpc request with the input
configuration for further processing. For more information on defining commands
run 'cue help cmd' or go to cuelang.org/pkg/cmd.

For more information on writing CUE configuration files see cuelang.org.

Usage:
  cue [command]

Available Commands:
  cmd         run a user-defined shell command
  completion  Generate completion script
  def         print consolidated definitions
  eval        evaluate and print a configuration
  export      output data in a standard format
  fix         rewrite packages to latest standards
  fmt         formats CUE configuration files
  get         add dependencies to the current module
  help        Help about any command
  import      convert other formats to CUE files
  mod         module maintenance
  trim        remove superfluous fields
  version     print CUE version
  vet         validate data

Flags:
  -E, --all-errors   print all available errors
  -h, --help         help for cue
  -i, --ignore       proceed in the presence of errors
  -s, --simplify     simplify output
      --strict       report errors for lossy mappings
      --trace        trace computation
  -v, --verbose      print information about progress

Additional help topics:
  cue commands   user-defined commands
  cue filetypes  supported file types and qualifiers
  cue flags      common flags for composing packages
  cue injection  inject files or values into specific fields for a build
  cue inputs     package list, patterns, and files

Use "cue [command] --help" for more information about a command.

下面通過一些具體的例子看看如何使用 CUE 。

JSON 超集

CUE是JSON的一個超集。它增加了以下的便利性。

  • C風格的注釋。

  • 引號可以從字段名中省略,沒有特殊字符。

  • 字段末尾的逗號是可選的。

  • 列表中最后一個元素后的逗號是允許的。

  • 外層大括號是可選的。

JSON對象在CUE中被稱為結(jié)構。一個對象的成員被稱為一個字段。

假設我們有 json.cue 文件如下 :

one: 1
two: 2

// A field using quotes.
"two-and-a-half": 2.5

list: [
	1,
	2,
	3,
]

m: {
    key1: "v1"
    key2: "v2"
}

可以通過 cue export json.cue 看看生成之后的 json 數(shù)據(jù) :

{
    "one": 1,
    "two": 2,
    "two-and-a-half": 2.5,
    "list": [
        1,
        2,
        3
    ],
    "m": {
        "key1": "v1",
        "key2": "v2"
    }
}
  • cue export 可以把 cue 文件轉(zhuǎn)化成 json、yamltext 等類型的文件

    • 轉(zhuǎn)化成 json cue export json.cue --out json

    • 轉(zhuǎn)化成 yaml cue export json.cue --out yaml

    • 轉(zhuǎn)化成 text cue export json.cue --out text

  • 輸出到文件 cue export json.cue --out json --outfile json.cue.json

可以通過 cue help export 查看詳細的幫助文檔

類型是值

CUE合并了值和類型的概念。下面是這個demo的演示,分別展示了一些數(shù)據(jù),這個數(shù)據(jù)的可能模式,以及介于兩者之間的東西:一個典型的CUE約束條件。

Data

moscow: {
  name:    "Moscow"
  pop:     11.92M
  capital: true
}

Schema

municipality: {
  name:    string
  pop:     int
  capital: bool
}

CUE:

largeCapital: {
  name:    string
  pop:     >5M
  capital: true
}

一般來說,在CUE中,人們從一個廣義的模式定義開始,描述所有可能的實例,然后針對特定的用例縮小這些定義的范圍,直到剩下一個具體的數(shù)據(jù)實例。

重復的字段

  • CUE允許重復的字段定義,只要它們不沖突。

  • 對于基本類型的值,這意味著它們必須是相等的。

  • 對于結(jié)構,字段被合并,重復的字段被遞歸處理。

  • 對于列表,所有的元素必須相應地匹配

假設的 dup.cue 內(nèi)容如下 :

a: 4
a: 4

s: { b: 2 }
s: { c: 2 }

l: [ 1, 2 ]
l: [ 1, 2 ]

通過 cue eval dup.cue 可以得到合并后的內(nèi)容 :

a: 4
s: {
    b: 2
    c: 2
}
l: [1, 2]
  • 也可以通過 export 命令生成 json/yaml 等文件看一下

如果key一樣,但是value 不一樣,會有什么樣的情況呢 ,修改 dup.cue 的文件內(nèi)容如下 :

a: 4
a: 5

s: { b: 2 }
s: { c: 2 }

l: [ 1, 2 ]
l: [ 1, 3 ]

這時再次執(zhí)行 cue eval dup.cue ,則會報錯 :

a: conflicting values 5 and 4:
    ./dup.cue:1:4
    ./dup.cue:2:4
l.1: conflicting values 3 and 2:
    ./dup.cue:7:9
    ./dup.cue:8:9

限制條件

約束規(guī)定了哪些值是允許的。對CUE來說,它們只是像其他東西一樣的值,但在概念上,它們可以被解釋為介于類型和具體值之間的東西。

但是約束也可以減少模板。如果一個約束定義了一個具體的值,那么就沒有必要在這個約束所適用的值中指定它。

假設 check.cue 文件如下 :

schema: {
    name:  string
    age:   int
    human: true // always true
}

viola: schema
viola: {
    name: "Viola"
    age:  38
}

這個文件的含義如下 :

  • schema 定義了約束, human 只能為 true ,后續(xù)在賦值時不能修改為其他的值,否則會報錯

  • viola: schema 表示繼承了 schema 的定義,引用了 schema 的約束

  • viola: { ... 是真正的賦值

執(zhí)行 cue eval check.cue 可以看到渲染之后的數(shù)據(jù)

schema: {
    name:  string
    age:   int
    human: true
}
viola: {
    name:  "Viola"
    age:   38
    human: true
}

這時把 check.cue 修改成如下這樣會有什么樣的輸入呢 ?

schema: {
    name:  string
    age:   int
    human: true // always true
}
viola: schema
viola: {
    name: "Viola"
    age:  38
    human: false
}

執(zhí)行 cue eval check.cue

viola.human: conflicting values false and true:
    ./check.cue:4:12
    ./check.cue:6:8
    ./check.cue:10:12

可以看到給 human 賦值為 false 報錯了

Definitions

在CUE中,模式通常被寫成 定義 。定義 是一個字段,其標識符以#或_#開頭。這告訴CUE它們是用來驗證的,不應該作為數(shù)據(jù)輸出;它們可以不被指定。

一個 定義 也告訴CUE允許的全部字段。換句話說,定義 定義了 "封閉 "的結(jié)構。在結(jié)構中包括一個...可以使其保持開放。

假設 schema.cue 文件內(nèi)容如下 :

#Conn: {
    address:  string
    port:     int
    protocol: string
    // ...    // uncomment this to allow any field
}

lossy: #Conn & {
    address:  "1.2.3.4"
    port:     8888
    protocol: "udp"
    // foo: 2 // uncomment this to get an error
}
  • #Conn 申明了一個定義

  • lossy 引用了這個定義并且實例化數(shù)據(jù),在實例化時會按照 schema 進行校驗,在如下情況都會報錯

    • 多了字段

    • 少了字段

    • 字段類型不匹配

執(zhí)行 cue export schema.cue 查看 :

{
    "lossy": {
        "address": "1.2.3.4",
        "port": 8888,
        "protocol": "udp"
    }
}

驗證

約束條件可以用來驗證具體實例的值。它們可以應用于CUE數(shù)據(jù),或直接應用于YAML或JSON。

假設 schema.cue 內(nèi)容如下 :

#Language: {
	tag:  string
	name: =~"^\\p{Lu}" // Must start with an uppercase letter.
}
languages: [...#Language]
  • languages: [...#Language] 可變長的一個列表 ,可以對照 languages: [#Language] 的 eval 輸出看一下區(qū)別

    // languages: [...#Language] 的輸出
    #Language: {
        tag:  string
        name: =~"^\\p{Lu}"
    }
    languages: []
    // languages: [#Language] 的輸出
    #Language: {
        tag:  string
        name: =~"^\\p{Lu}"
    }
    languages: [{
        tag:  string
        name: =~"^\\p{Lu}"
    }]


data.yaml 的內(nèi)容如下 :

languages:
  - tag: en
    name: English
  - tag: nl
    name: dutch
  - tag: no
    name: Norwegian

執(zhí)行 cue vet schema.cue data.yaml 可以看到會報錯

languages.1.name: invalid value "dutch" (does not match =~"^\\p{Lu}"):
    ./schema.cue:3:8
    ./data.yaml:5:12
  • dutch 驗證失敗,必須以大寫字母開頭

順序不重要

CUE的基本操作是這樣定義的:你結(jié)合兩個配置的順序與結(jié)果無關。

這是CUE的關鍵屬性,它使人類和機器很容易對數(shù)值進行推理,并使高級工具和自動化成為可能。

假設 order.cue 內(nèi)容如下 :

a: {x: 1, y: int}
a: {x: int, y: 2}

b: {x: int, y: 2}
b: {x: 1, y: int}

執(zhí)行 cue eval order.cue 得到 :

a: {
    x: 1
    y: 2
}
b: {
    x: 1
    y: 2
}
  • 可以看到,定義和賦值誰先誰后都沒有影響

單項結(jié)構的折疊

在JSON中,人們定義了嵌套值,一次一個值。另一種方式是,JSON配置是一組路徑-值對。

在CUE中,人們定義了一組路徑,并一次性地應用具體的值或約束條件。由于CUE的順序獨立性,數(shù)值會被合并。

這個例子顯示了一些路徑值對,以及一個應用于這些路徑值的約束來驗證它們。

fold.cue 內(nèi)容如下 :

// path-value pairs
outer: middle1: inner: 3
outer: middle2: inner: 7

// collection-constraint pair
outer: [string]: inner: int

執(zhí)行 cue export fold.cue

{
    "outer": {
        "middle1": {
            "inner": 3
        },
        "middle2": {
            "inner": 7
        }
    }
}

“什么是CUE”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)
推薦閱讀:
  1. 什么是PHP
  2. 什么是python

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI