BOSHのops-fileをyttのoverlayで書き直す

cf-for-k8sで多用されている、yttのoverlayの書き方を身に付ける練習として、BOSHのops fileをyttで書き直してみる。 題材として、https://bosh.io/docs/cli-ops-files/#opsyttで実現してみる。

次のドキュメントを参考にした。

以下のbase.ymlをカスタマイズしていく。

key: 1

key2:
  nested:
    super_nested: 2
  other: 3

array: [4,5,6]

items:
- name: item7
- name: item8
- name: item8

目次

以降、デフォルトのOpeationである@overlay/mergeは省略し、記述していない。

Hash

Set key to 10 ...

ops-fileの場合

- type: replace
  path: /key
  value: 10

yttの場合

hash-replace.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
key: 10
$ ytt -f base.yml -f hash-replace.yml
key: 10
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

overlay fileの---の上の#@overlay/match by=***は、複数あるYAMLブロックのうちのどのブロックを対象とするかを指定する条件式である。
BOSHの場合は1つのYAMLブロックしかサポートしていないため、移行の際はby=overlay.allまたは、念のためby=overlay.all,expects=1で良いはず。
Kubernetesの場合は通常、複数のYAMLブロックを扱うので、by=overlay.subset({"kind": "Ingress"})などで条件を絞る必要がある。


Remove key...

ops-fileの場合

- type: remove
  path: /key

yttの場合

hash-remove.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
#@overlay/remove
key: 
$ ytt -f base.yml -f hash-remove.yml
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Errors because key_not_there is expected (and does not have ?)...

ops-fileの場合

- type: replace
  path: /key_not_there
  value: 10

yttの場合

hash-replace-error.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
key_not_there: 10
$ ytt -f base.yml -f hash-replace-error.yml 
ytt: Error: Overlaying (in following order: hash-replace-error.yml): Document on line hash-replace-error.yml:4: Map item (key 'key_not_there') on line hash-replace-error.yml:5: Expected number of matched nodes to be 1, but was 0

Errors because key_not_there is expected (does not have ?)...

ops-fileの場合

- type: remove
  path: /key_not_there

yttの場合

hash-remove-error.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
#@overlay/remove
key_not_there:
$ ytt -f base.yml -f hash-remove-error.yml 
ytt: Error: Overlaying (in following order: hash-remove-error.yml): Document on line hash-remove-error.yml:4: Map item (key 'key_not_there') on line hash-remove-error.yml:6: Expected number of matched nodes to be 1, but was 0

Creates new_key and sets it to 10 (note the ?)...

ops-fileの場合

- type: replace
  path: /new_key?
  value: 10

yttの場合

hash-create.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
#@overlay/match missing_ok=True
new_key: 10
$ ytt -f base.yml -f hash-create.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8
new_key: 10

Requires that key2 and nested hashes exist; and sets super_nested to 10...

ops-fileの場合

- type: replace
  path: /key2/nested/super_nested
  value: 10

yttの場合

hash-replace-nested.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
key2:
  nested:
    super_nested: 10
$ ytt -f base.yml -f hash-replace-nested.yml 
key: 1
key2:
  nested:
    super_nested: 10
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Requires that key2 and nested hashes exist; and removes super_nested...

yaml pacthの場合

- type: remove
  path: /key2/nested/super_nested

yttの場合

hash-remove-nested.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
key2:
  nested:
   #@overlay/remove
   super_nested:
$ ytt -f base.yml -f hash-remove-nested.yml
key: 1
key2:
  nested: {}
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Requires that key2 hash exists; allows nested, another_nested and super_nested not to exist because ? carries over to nested keys; and creates another_nested and super_nested before setting super_nested to 10...

ops-fileの場合

- type: replace
  path: /key2/nested?/another_nested/super_nested
  value: 10

yttの場合

hash-create-nested.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
key2:
  nested:
   #@overlay/match missing_ok=True
   another_nested:
     super_nested: 10
$ ytt -f base.yml -f hash-create-nested.yml 
key: 1
key2:
  nested:
    super_nested: 2
    another_nested:
      super_nested: 10
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Array

Requires array to exist and be an array; and replaces 0th item in array array with 10...

ops-fileの場合

- type: replace
  path: /array/0
  value: 10

yttの場合

array-replace-0th.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
array:
#@overlay/match by=overlay.index(0)
- 10
$ ytt -f base.yml -f array-replace-0th.yml
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 10
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Requires array to exist and be an array; and removes the 0th item in array...

ops-fileの場合

- type: remove
  path: /array/0

yttの場合

array-remove-0th.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
array:
#@overlay/match by=overlay.index(0)
#@overlay/remove
- 
$ ytt -f base.yml -f array-remove-0th.yml      
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Requires array to exist and be an array; and appends 10 to the end of array...

ops-fileの場合

- type: replace
  path: /array/-
  value: 10

yttの場合

array-append.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
array:
#@overlay/append
- 10
$ ytt -f base.yml -f array-append.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
- 10
items:
- name: item7
- name: item8
- name: item8

Creates array2 array since it does not exist; and appends 10 to the end of array2...

ops-fileの場合

- type: replace
  path: /array2?/-
  value: 10

yttの場合

array-create.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
#@overlay/match missing_ok=True
array2:
- 10
$ ytt -f base.yml -f array-create.yml
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8
array2:
- 10

Requires array to exist and be an array; and inserts 10 after 0th item in array array...

ops-fileの場合

- type: replace
  path: /array/0:after
  value: 10

yttの場合

array-insert-after.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
array:
#@overlay/match by=overlay.index(0)
#@overlay/insert after=True
- 10
$ ytt -f base.yml -f array-insert-after.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 10
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Requires array to exist and be an array; and inserts 10 before 0th item at the beginning of array array...

ops-fileの場合

- type: replace
  path: /array/0:before
  value: 10

yttの場合

array-insert-before.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
array:
#@overlay/match by=overlay.index(0)
#@overlay/insert before=True
- 10
$ ytt -f base.yml -f array-insert-before.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 10
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8

Arrays of hashes

Finds and removes array item with matching key name with value item7...

ops-fileの場合

- type: remove
  path: /items/name=item7

yttの場合

find-and-remove-array-item.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
items:
#@overlay/match by="name"
#@overlay/remove
- name: item7
$ ytt -f base.yml -f find-and-remove-array-item.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item8
- name: item8

Errors because there are two values that have item8 as their name...

ops-fileの場合

- type: replace
  path: /items/name=item8/count
  value: 10

yttの場合

find-and-replace-array-item-error.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
items:
#@overlay/match by="name", missing_ok=True
- name: item8
  count: 10
$ ytt -f base.yml -f find-and-replace-array-item-error.yml 
ytt: Error: Overlaying (in following order: find-and-replace-array-item-error.yml): Document on line find-and-replace-array-item-error.yml:4: Map item (key 'items') on line find-and-replace-array-item-error.yml:5: Array item on line find-and-replace-array-item-error.yml:7: Expected number of matched nodes to be 1, but was 2 (lines: base.yml:12, base.yml:13)

Appends array item with matching key name with value item9 because values ends with ? and item does not exist; creates count and sets it to 10 within created array item...

ops-fileの場合

- type: replace
  path: /items/name=item9?/count
  value: 10

yttの場合

find-and-append-array-item.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
items:
#@overlay/match by="name", missing_ok=True
- name: item9
  count: 10
$ ytt -f base.yml -f find-and-append-array-item.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item7
- name: item8
- name: item8
- name: item9
  count: 10

Finds array item with matching key name with value item7; and adds hash name: item6 before found array item...

ops-fileの場合

- type: replace
  path: /items/name=item7:before
  value:
    name: item6

yttの場合

find-and-insert-array-item-before.yml

#@ load("@ytt:overlay", "overlay")

#@overlay/match by=overlay.all
---
items:
#@overlay/match by=overlay.subset({"name": "item7"})
#@overlay/insert before=True
- name: item6
$ ytt -f base.yml -f find-and-insert-array-item-before.yml 
key: 1
key2:
  nested:
    super_nested: 2
  other: 3
array:
- 4
- 5
- 6
items:
- name: item6
- name: item7
- name: item8
- name: item8