cuelang kubernetes チュートリアル#1
cuelang を触っている。まだ入門でたとは言えない感じだが、kubernetes チュートリアルが面白い。2周目で人に説明できるくらいになってきた。
https://github.com/cuelang/cue/tree/master/doc/tutorial/kubernetes
cue import オプション
cue import ./... -p kube -l 'strings.ToCamel(kind)' -l metadata.name -f -R -p, --package string package name for non-CUE files 非CUEファイルのパッケージ名 -l, --path stringArray CUE expression for single path component シングルパスコンポーネントのCUE式 -f, --force force overwriting existing files ファイル上書き -R, --recursive recursively parse string values 文字列値を再帰的に解析する
cue import ./... -p kube -l 'strings.ToCamel(kind)' -l metadata.name -f で起きること
- ./... 下の yaml から cue を生成 kube.cue -> kube.yaml
- package kube を付与させる
- オブジェクトは -l 'strings.ToCamel(kind)' -l metadata.name 内に格納される オブジェクトを一意にする
- ファイル上書き
tree
$ tree . | head . └── services ├── frontend │ ├── bartender │ │ ├── kube.cue │ │ └── kube.yaml │ ├── breaddispatcher │ │ ├── kube.cue │ │ └── kube.yaml
services/frontend/bartender/kube.yaml
apiVersion: v1 kind: Service metadata: name: bartender : --- apiVersion: apps/v1 kind: Deployment metadata: name: bartender :
services/frontend/bartender/kube.cue
package kube service: bartender: { apiVersion: "v1" kind: "Service" metadata: { name: "bartender" : deployment: bartender: { apiVersion: "apps/v1" kind: "Deployment" metadata: name: "bartender" :
cat mon/prometheus/configmap.cue
yaml 内に文字列として yaml が埋め込まれている。cue にしてもまだ文字列としてのyamlのまま、これが気に入らないと。
mon/prometheus/configmap.cue
package kube apiVersion: "v1" kind: "ConfigMap" metadata: name: "prometheus" data: { "alert.rules": """ <--- ここらへんが気に入らない groups: - name: rules.yaml
cue import ./... -p kube -l 'strings.ToCamel(kind)' -l metadata.name -f -R で起きること
-Rオプションは、構成ファイルに埋め込まれた構造化されたYAMLまたはJSON文字列を検出し、これらを再帰的に変換しようとする
- alert.rules の階層に _cue_alert_rules が出現
- _cue_alert_rules の値は alert.rules の値を再帰的に解析したもの
- アンダースコア(_)で始まるフィールドは、構成ファイルの出力時(exportとかevalかな)には含まれません
- "alert.rules" の値は _cue_alert_rules の値をマーシャルしたもの
- _cue_alert_rules の アンダースコア始まりはhiddenフィールド https://cuelang.org/docs/tutorials/tour/references/hidden/
- "encoding/yaml" を yaml656e63 としてインポート
mon/prometheus/configmap.cue
package kube import yaml656e63 "encoding/yaml" <--- yaml656e63 configMap: prometheus: { apiVersion: "v1" kind: "ConfigMap" metadata: name: "prometheus" data: { "alert.rules": yaml656e63.Marshal(_cue_alert_rules) <--- yaml656e63, _cue_alert_rules let _cue_alert_rules = { <--- _cue_alert_rules groups: [{ name: "rules.yaml" rules: [{ alert: "InstanceDown" expr: "up == 0" for: "30s" labels: severity: "page" annotations: { description: "{{$labels.app}} of job {{ $labels.job }} has been down for more than 30 seconds." summary: "Instance {{$labels.app}} down"
cue eval ./mon/prometheus -e configMap.prometheus
./mon/prometheus 下のファイルのうち オブジェクト configMap.prometheus の内容について評価 次が得られる。eval で出てきたのは cue であって yaml じゃない
$ cue eval ./mon/prometheus -e configMap.prometheus apiVersion: "v1" kind: "ConfigMap" metadata: { name: "prometheus" } data: { "alert.rules": """ <--- cue内 yaml 文字列 groups: - name: rules.yaml rules: - alert: InstanceDown expr: up == 0 for: 30s labels: severity: page annotations: description: '{{$labels.app}} of job {{ $labels.job }} has been down for more than 30 seconds.' summary: Instance {{$labels.app}} down
もとのyaml。完全一致でないが同等と言えるだろう。
apiVersion: v1 kind: ConfigMap metadata: name: prometheus data: alert.rules: |- groups: - name: rules.yaml rules: - alert: InstanceDown expr: up == 0 for: 30s labels: severity: page annotations: description: '{{$labels.app}} of job {{ $labels.job }} has been down for more than 30 seconds.' summary: Instance {{$labels.app}} down
yaml に export。yaml 内 yaml のコメントは消えているが、おなじと言える。
$ cue export ./mon/prometheus -e configMap.prometheus --out yaml apiVersion: v1 kind: ConfigMap metadata: name: prometheus data: alert.rules: | groups: - name: rules.yaml rules: - alert: InstanceDown expr: up == 0 for: 30s labels: severity: page annotations: description: '{{$labels.app}} of job {{ $labels.job }} has been down for more than 30 seconds.' summary: Instance {{$labels.app}} down
cue から yaml を生成するときどうするの
yamlからcueを生成できるのは分かった。cueのチュートリアルやったのでcueはサイズを減らしたり、validationできるのは分かる。 cueからyaml生成は cue export --out yaml。 import でオブジェクトを一意にするため -l 'strings.ToCamel(kind)' -l metadata.name で2階層沈めた。 kind は型チェックに用いられ metaname は省略表記に用いられるのだろうなあ。 しかし、これでは取り出すとき -e configMap.prometheus 2階層(kind)(metaname)指定することになる。面倒です。どうすれば? チュートリアル進めればわかるんだけど。