Jq заменить существующий JSON комплексом значений - PullRequest
0 голосов
/ 08 апреля 2019

Мне нужно создать список параметров CloudFormation (config.json) во время CodeBuild. У меня есть репозиторий Bash в моем репо, который будет принимать несколько параметров. Это будет либо производство, постановка или разработка.

Вот генератор.json. Значения здесь будут использоваться для генерации config.json.

{
  "Parameters" : {
    "FargateStackSuffix" : "environment-fargate",
    "VPCStackSuffix": "environment-base-vpc",
    "ContainerPort" : "80",
    "ContainerCpu" : "256",
    "ContainerMemory" : "512",
    "Path" : "*",
    "productionDesiredCount" : "3",
    "stagingDesiredCount" : "2",
    "developmentDesiredCount" : "1",
    "ELBType" : "application",
    "ELBIpAddressType": "ipv4",
    "productionZone": "service.example.com",
    "stagingZone": "service-staging.example.com",
    "devZone": "service-dev.example.com"
  }
}

Например:

./generate.sh my-service production

будет генерировать это:

{
  "Parameters" : {
    "FargateStackSuffix" : "production-fargate",
    "VPCStackSuffix": "production-base-vpc",
    "ServiceName" : "myservice",
    "EnvironmentName" : "production",
    "ContainerPort" : "80",
    "ContainerCpu" : "256",
    "ContainerMemory" : "512",
    "Path" : "*",
    "DesiredCount" : "3",
    "ELBType" : "application",
    "ELBIpAddressType": "ipv4",
    "Zone": "myservice.example.com"
  }
}

Как видите, есть небольшая замена на основе дополнений. Простое перебора ключей не сделает этого. Есть ли способ сделать все необходимые преобразования, просто JQ?

РЕДАКТИРОВАТЬ : В итоге я использовал несколько sed для фильтрации и замены нескольких значений. Теперь мне нужно заменить соответствующий DesiredCount:

cat .codedeploy/generator.json | jq '[paths(type == "string" and contains("DesiredCount"))]'
[]

Моя проблема в том, что он возвращает пустой массив.

Ответы [ 2 ]

0 голосов
/ 14 мая 2019

Вот один из таких способов, которым вы можете создать этот JSON. Возможно, сложная часть здесь генерирует динамическое имя для окружения DesiredCount и Zone. Но JQ справляется с этим довольно легко.

$ jq --arg ServiceName "myservice" --arg EnvironmentName "production" '.Parameters |=
{
    FargateStackSuffix,
    VPCStackSuffix,
    $ServiceName,
    $EnvironmentName,
    ContainerPort,
    ContainerCpu,
    ContainerMemory,
    Path,
    DesiredCount: ."\($EnvironmentName)DesiredCount",
    ELBType,
    ELBIpAddressType,
    Zone: ."\($EnvironmentName)Zone"
}
' generator.json > config.json

$ cat config.json
{
  "Parameters": {
    "FargateStackSuffix": "environment-fargate",
    "VPCStackSuffix": "environment-base-vpc",
    "ServiceName": "myservice",
    "EnvironmentName": "production",
    "ContainerPort": "80",
    "ContainerCpu": "256",
    "ContainerMemory": "512",
    "Path": "*",
    "DesiredCount": "3",
    "ELBType": "application",
    "ELBIpAddressType": "ipv4",
    "Zone": "service.example.com"
  }
}
0 голосов
/ 14 мая 2019

Вы можете использовать конструкцию объекта, чтобы сделать это.

cat generator.json | jq --arg variable $variable '{Parameters: {DesiredCount: .Parameters.developmentDesiredCount, Zone: .Parameters.devZone, environmentName: "Production", var: $variable}}'

Здесь я показал несколько решений, чтобы помочь вам.

  1. Вы можете ссылаться на параметры в generator.json, используя точечную запись в значении этого поля в новом объекте.
  2. Вы можете просто определить строку
  3. Вы можете использовать флаг args для передачи переменной bash.

Вывод (неполный, но показывает решение)

{
  "Parameters": {
    "DesiredCount": "1",
    "Zone": "service-dev.example.com",
    "environmentName": "Production",
    "var": "VariableString"
  }
}
...