如何使用 `yq` 将属性设置为多行字符串?

问题描述 投票:0回答:4

我有一个类似于以下内容的证书文件:

-------BEGIN CERTIFICATE-------
asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
-------END CERTIFICATE--------

我还有一个 YAML 文件(OpenShift

Template
),如下所示:

apiVersion: v1
kind: Template
objects:
- apiVersion: v1
  kind: Route
  tls:
    certificate:
    key:
  someOther: stuff

如何使用

yq
将上面 YAML 文件中属性
certificate
的值设置为证书文件的内容,以便输出看起来有点像这样:

apiVersion: v1
...
    certificate: |
      -------BEGIN CERTIFICATE-------
      asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
      qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
      -------END CERTIFICATE--------

互联网搜索和文档都没有任何帮助。我得到的最接近的是使用以下内容:

yq w /tmp/template.yaml objects[0].tls.certificate "\n$(cat cert.pem)"

...这给我留下了以下输出:

certificate: !!binary |
      fC0KLS0tLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0tLQphc2RvcWlqZXBvcWp3ZTFpND
      lpMTIwOTQxcDJqNG9tc2zDYXNkYWpzZMNxd2Vxd2UKcXdlbHFqd2vDYXNkbGFqc8O2bGtq
      YXNsZGtqYWtsanNkbGtqYXNkYXNkcGlxd2UKLS0tLS0tLUVORCBDRVJUSUZJQ0FURS0tLS
      0tLS0t

...奇怪的是我想在

!!binary |
之前添加的内容的 base64 编码变体。知道发生了什么以及如何实现所需的输出吗?

bash base64 yaml yq
4个回答
7
投票

请注意,在 bash 中,当您使用 '$(..)' 时,它将修剪尾随换行符(这就是 yaml 字符串块以

|-
而不是
|
开头的原因。

要获得

|
(包括尾随的新行),您需要:

IFS= read -rd '' output < <(cat cert.pem)
output=$output yq e '.objects[0].tls.certificate = strenv(output)' myfile.yml

免责声明:我写的是yq


4
投票

您可以使用

load_str
运算符从文件加载字符串并将其分配给属性:

yq '.objects[0].tls.certificate = load_str("cert.pem")' template.yaml

(上面,

template.yaml
表示 OpenShift 模板 YAML 文件的路径,如果这不明显的话)

上述命令将在您的情况下产生以下输出:

apiVersion: v1
kind: Template
objects:
  - apiVersion: v1
    kind: Route
    tls:
      certificate: |
        -------BEGIN CERTIFICATE-------
        asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
        qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
        -------END CERTIFICATE--------
      key:
    someOther: stuff

2
投票

我已经用

yq3
测试了@Inian建议并且它有效。

也可以在

yq4
中通过以下语法实现:

模板.yml

# template.yml
apiVersion: v1
kind: Template
objects:
  - apiVersion: v1
    kind: Route
    tls:
      certificate:
      key:
    someOther: stuff

cert.pem

-------BEGIN CERTIFICATE-------
asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
-------END CERTIFICATE--------

命令

yq eval '.objects[0].tls.certificate = "'"$(< cert.pem)"'"' template.yml

输出

apiVersion: v1
kind: Template
objects:
  - apiVersion: v1
    kind: Route
    tls:
      certificate: |-
        -------BEGIN CERTIFICATE-------
        asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
        qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
        -------END CERTIFICATE--------
      key:
    someOther: stuff

0
投票

我可能发现了一个错误@mike.f

#!/usr/bin/env bash

###
# ❯ yq --version
# yq (https://github.com/mikefarah/yq/) version 4.27.5
##

echo "########## Multiline string is set ##########"
cat > cert.pem << EOF
-------BEGIN CERTIFICATE-------
asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
-------END CERTIFICATE--------
EOF

IFS= read -rd '' cert < <(cat cert.pem)
export cert=$cert
yq --null-input '.cert = strenv(cert)'

echo "########## Multiline string is NOT set ##########"
cat > flatcar_ignition.yml << EOF
storage:
  files:
    - path: /opt/k8s_setup.sh
      filesystem: root
      contents:
        inline: ""
      mode: 0744
      user:
        id: 500
      group:
        id: 501
EOF
cat > k8s_setup.sh << EOF
#!/usr/bin/env bash
echo "test1" > /test.txt
echo "test2" >> /test.txt
echo "test3" >> /test.txt
EOF

IFS= read -rd '' k8s_setup < <(cat k8s_setup.sh)
export k8s_setup=$k8s_setup
yq e '.storage.files[0].contents.inline = strenv(k8s_setup)' flatcar_ignition.yml

结果:

❯ ./test.sh
########## Multiline string is set ##########
cert: |
  -------BEGIN CERTIFICATE-------
  asdoqijepoqjwe1i49i120941p2j4omslasdajsdqweqwe
  qwelqjwkasdlajsölkjasldkjakljsdlkjasdasdpiqwe
  -------END CERTIFICATE--------

########## Multiline string is NOT set ##########
storage:
  files:
    - path: /opt/k8s_setup.sh
      filesystem: root
      contents:
        inline: "#!/usr/bin/env bash\necho \"test1\" > /test.txt\necho \"test2\" >> /test.txt\necho \"test3\" >> /test.txt\n"
      mode: 0744
      user:
        id: 500
      group:
       id: 501
© www.soinside.com 2019 - 2024. All rights reserved.