yq - добавить многострочную строку

Я использую yq (аналогично jq, но для файлов yaml). Моя цель - сделать следующее. У меня есть файл сертификата, похожий на

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

и у меня есть файл yaml (в данном случае шаблон Openshift), который выглядит так

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

Теперь моя цель - вставить сертификат в yaml, чтобы результат выглядел примерно так:

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

что, как ни странно, является значением в кодировке base64 того, которое я хотел добавить, которому предшествует!! Есть идеи, что происходит и как я могу достичь желаемого результата?

4 ответа

Обратите внимание, что в bash, когда вы используете «$(..)», он обрезает конечные символы новой строки (поэтому строковый блок yaml начинается с |-вместо .

Получить |(и включая конечную новую строку), вам необходимо:

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

Отказ от ответственности: я написал yq

Вы можете использовать load_strоператор для загрузки строки из файла и присвоения ее результата свойству:

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

(выше,template.yamlобозначает путь к вашему YAML-файлу шаблона OpenShift, если это не очевидно)

В вашем случае приведенная выше команда выдаст следующий результат:

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

Я проверил предложение @Inian с помощью yq3 и это работает.

Этого также можно добиться в yq4 со следующим синтаксисом:

template.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

Возможно, я нашел ошибку @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
Другие вопросы по тегам