如何用 ytt 替换多行字符串中包含的数组项的映射值?
How can I replace map value of array item contained in a multi-line string with ytt?
我正在尝试使用 ytt 叠加层替换我的秘密 class 中 this gist example replacing only part of a multi-line string 之后的 objectName
,但它最终会附加一个新项目而不是替换现有项目一。我怎样才能让它适用于这种情况?
输入文件
db_secret.yaml
kind: SecretProviderClass
metadata:
namespace: default
name: db_credentials
spec:
provider: aws
parameters:
objects: |
- objectName: TO_BE_REPLACED_BY_YTT
objectType: "secretsmanager"
jmesPath:
- path: username
objectAlias: dbusername
- path: password
objectAlias: dbpassword
overlay.yaml
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:yaml", "yaml")
#@ load("@ytt:data", "data")
#@ def updates():
- objectName: #@ data.values.db_secret_name
#@ end
#@overlay/match by=overlay.subset({"kind": "SecretProviderClass", "metadata": {"name": "db_credentials"}})
---
spec:
provider: aws
parameters:
#@overlay/replace via=lambda a,_: yaml.encode(overlay.apply(yaml.decode(a), updates()))
objects:
值-staging.yaml
db_secret_name: db-secret-staging
ytt 输出:
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
namespace: default
name: db_credentials
spec:
provider: aws
parameters:
objects: |
- objectName: TO_BE_REPLACED_BY_YTT
objectType: secretsmanager
jmesPath:
- path: username
objectAlias: dbusername
- path: password
objectAlias: dbpassword
- objectName: db-secret-staging
值得注意的是,被覆盖的 YAML 值本身就是一个数组。它是一个包含一项的数组,但仍然是一个数组。
为了到达具有 objectName
地图项的地图,您需要首先匹配其父项:包含数组项的地图。
最持久的方法是选择具有包含 objectName
键的映射的数组项。你可以这样说:
#@ def updates():
+ #@overlay/match by=lambda idx,left,right: "objectName" in left
- objectName: #@ data.values.db_secret_name
#@ end
可以读作:“在被覆盖的数组值中(又名 'left'),找到其值具有映射的数组项,其键包含字符串“objectName”...合并值this 数组项(即此叠加层中数组项中的地图)转换为 that 匹配的地图。
(游乐场:https://carvel.dev/ytt/#gist:https://gist.github.com/pivotaljohn/9593f971ac5962055ff38c5eeaf1df11)
使用叠加层时,将值树可视化会很有帮助。文档中有一些很好的例子:https://carvel.dev/ytt/docs/v0.40.0/yaml-primer/
此外,据报道有一个 recent-ish 视频博客 post 可以帮助人们使用 ytt
叠加层升级:https://carvel.dev/blog/primer-on-ytt-overlays/
我正在尝试使用 ytt 叠加层替换我的秘密 class 中 this gist example replacing only part of a multi-line string 之后的 objectName
,但它最终会附加一个新项目而不是替换现有项目一。我怎样才能让它适用于这种情况?
输入文件
db_secret.yaml
kind: SecretProviderClass
metadata:
namespace: default
name: db_credentials
spec:
provider: aws
parameters:
objects: |
- objectName: TO_BE_REPLACED_BY_YTT
objectType: "secretsmanager"
jmesPath:
- path: username
objectAlias: dbusername
- path: password
objectAlias: dbpassword
overlay.yaml
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:yaml", "yaml")
#@ load("@ytt:data", "data")
#@ def updates():
- objectName: #@ data.values.db_secret_name
#@ end
#@overlay/match by=overlay.subset({"kind": "SecretProviderClass", "metadata": {"name": "db_credentials"}})
---
spec:
provider: aws
parameters:
#@overlay/replace via=lambda a,_: yaml.encode(overlay.apply(yaml.decode(a), updates()))
objects:
值-staging.yaml
db_secret_name: db-secret-staging
ytt 输出:
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
namespace: default
name: db_credentials
spec:
provider: aws
parameters:
objects: |
- objectName: TO_BE_REPLACED_BY_YTT
objectType: secretsmanager
jmesPath:
- path: username
objectAlias: dbusername
- path: password
objectAlias: dbpassword
- objectName: db-secret-staging
值得注意的是,被覆盖的 YAML 值本身就是一个数组。它是一个包含一项的数组,但仍然是一个数组。
为了到达具有 objectName
地图项的地图,您需要首先匹配其父项:包含数组项的地图。
最持久的方法是选择具有包含 objectName
键的映射的数组项。你可以这样说:
#@ def updates():
+ #@overlay/match by=lambda idx,left,right: "objectName" in left
- objectName: #@ data.values.db_secret_name
#@ end
可以读作:“在被覆盖的数组值中(又名 'left'),找到其值具有映射的数组项,其键包含字符串“objectName”...合并值this 数组项(即此叠加层中数组项中的地图)转换为 that 匹配的地图。
(游乐场:https://carvel.dev/ytt/#gist:https://gist.github.com/pivotaljohn/9593f971ac5962055ff38c5eeaf1df11)
使用叠加层时,将值树可视化会很有帮助。文档中有一些很好的例子:https://carvel.dev/ytt/docs/v0.40.0/yaml-primer/
此外,据报道有一个 recent-ish 视频博客 post 可以帮助人们使用 ytt
叠加层升级:https://carvel.dev/blog/primer-on-ytt-overlays/