Как в JQ условно изменить строковое значение на число? - PullRequest
2 голосов
/ 01 августа 2020

Я извлекаю секрет из SecretsManager в AWS и использую полученный JSON для создания файла параметров JSON, который может передать его в формирование облака. двигатель. К сожалению, SecretsManager хранит все значения в виде строк, поэтому, когда я пытаюсь передать эти значения в свой шаблон формирования облака, он потерпит неудачу, потому что он передает строку вместо числа, а некоторые параметры формирования облака должны быть числами (например, не строкой) .

В приведенном ниже примере я хочу сообщить JQ, что « HEALTH_CHECK_UNHEALTHY_THRESHOLD_COUNT » и « AUTOSCALING_MAX_CAPACITY » являются числами. Итак, я добавляю к ключу префикс «ЧИСЛО ::».

Это служит двум целям. Во-первых, он сообщает человеку, просматривающему этот секрет, что он будет преобразован в число, во-вторых, он сообщает JQ преобразовать строковое значение «2» в 2. Это нужно масштабировать, чтобы у меня были ключи 1..n которые необходимо преобразовать в JSON.

Рассмотрим это JSON:

{
  "NUMBER::AUTOSCALING_MAX_CAPACITY": "12",
  "SERVICE_PLATFORM_VERSION": "1.3.0",
  "HEALTH_CHECK_PROTOCOL": "HTTPS",
  "NUMBER::HEALTH_CHECK_UNHEALTHY_THRESHOLD_COUNT": "2"
}

Вот что я хотел бы сделать с JQ:

  1. JQ скопирует пары ключ / значение для большинства элементов в JSON «как есть». Если префикса «NUMBER ::» нет, они копируются «как есть».

  2. Однако, если ключ имеет префикс «NUMBER ::», я бы хотел должно произойти следующее:

    a. JQ удалит префикс «NUMBER ::» из имени ключа.

    b. JQ преобразует значение из строки в число.

Конечный результат - JSON, который выглядит следующим образом:

{
  "AUTOSCALING_MAX_CAPACITY": 12,
  "SERVICE_PLATFORM_VERSION": "1.3.0",
  "HEALTH_CHECK_PROTOCOL": "HTTPS",
  "HEALTH_CHECK_UNHEALTHY_THRESHOLD_COUNT": 2
}

What Я пробовал

. Я пытался использовать Map для этого с ограниченным успехом. В этом примере я ищу определенное поле c в основном в качестве теста. Я не хочу вызывать определенные c ключи по имени, а просто использую любой ключ, который начинается с «ЧИСЛО ::» для преобразования.

ПРИМЕЧАНИЕ. SECRET_STRING Переменная в приведенных ниже примерах содержит исходный код JSON.

 echo $SECRET_STRING | jq 'to_entries | map(if .key == "NUMBER::AUTOSCALING_MAX_CAPACITY"  then . + {"value":.value}  else . end ) | from_entries'**

Я также пытался использовать "tonumber" во всем JSON. JQ проверит все значения и посмотрит, сможет ли он преобразовать их в числа. Проблема в том, что он не работает, когда нажимает клавишу «SERVICE_PLATFORM_VERSION», так как обнаруживает «1.3.0» как число и пытается сделать это число, что, конечно, является подделкой.

Example: echo $SECRET_STRING | jq -r '.[] | tonumber'

Резюме Я хотел бы использовать JQ для преобразования JSON строковых значений в число, используя префикс «ЧИСЛО ::» в имени ключа.

Примечание : Эта проблема не возникает при попытке извлечь записи из хранилища параметров системного менеджера , поскольку AWS позволяет использовать «разрешающие» записи в виде строк или чисел. Этой функции нет в SecretsManager. Я также хотел бы использовать SecretsManager, чтобы предоставить список из 30 или более элементов конфигурации для настройки моего стека. В хранилище параметров вы должны настроить каждый элемент конфигурации как отдельную запись, что для нас стало настоящим кошмаром при обслуживании.

1 Ответ

4 голосов
/ 01 августа 2020

Выберите каждую запись с ключом, начинающимся с NUMBER::, и обновите ее, чтобы удалить этот префикс и преобразовать значение в число.

with_entries(
  select(.key | startswith("NUMBER::")) |= (
    (.key   |= ltrimstr("NUMBER::")) |
    (.value |= tonumber)
  )
)

Онлайн-демонстрация

...