Экранирование строки JSON внутри оболочки Jenkinsfile - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь избежать json-строки внутри jenkinsfile, но это немного сложно, что примеры, которые я проверил онлайн.

sshagent(credentials: ['keypair']) {
            sh """
                ssh ansible@ansible-server \
                '
# vars
src_env="${params.source_env}"
dest_env="${params.destination_env}"
src_prefix="${params.source_s3_prefix}"
dest_prefix="${params.destination_s3_prefix}"
region="${region}"
ch="${ch}"
aws_account="${aws_account}"

# Run ECS task
echo "---- Run ECS task ----"
task_id=$(aws ecs run-task \
  --cluster cluster-\${ch}-\${dest_env} \
  --task-definition \$td_id \
  --region \${region} \
  --overrides {\\\"containerOverrides\\\": [{\\\"name\\\": \\\"s3-sync\\\", \\\"environment\\\": [{\\\"name\\\": \\\"SRC_ENV\\\", \\\"value\\\": \\\"$${src_env}\\\"}, {\\\"name\\\": \\\"DEST_ENV\\\", \\\"value\\\": \\\"$${dest_env}\\\"}, {\\\"name\\\": \\\"SRC_PREFIX\\\", \\\"value\\\": \\\"$${src_prefix}\\\"}, {\\\"name\\\": \\\"DEST_PREFIX\\\", \\\"value\\\": \\\"$${dest_prefix}\\\"}]}], \\\"taskRoleArn\\\":  \\\"arn:aws:iam::$${aws_account}:role/$${ch}-$${dest_env}\\\"} \
  --query 'tasks[0].taskArn' \
  --output text | cut -d'/' -f 2)

                '
            """
}

Итак, проблема в том, чтобы избежать следующей строки json:

--overrides {\\\"containerOverrides\\\": [{\\\"name\\\": \\\"s3-sync\\\", \\\"environment\\\": [{\\\"name\\\": \\\"SRC_ENV\\\", \\\"value\\\": \\\"$${src_env}\\\"}, {\\\"name\\\": \\\"DEST_ENV\\\", \\\"value\\\": \\\"$${dest_env}\\\"}, {\\\"name\\\": \\\"SRC_PREFIX\\\", \\\"value\\\": \\\"$${src_prefix}\\\"}, {\\\"name\\\": \\\"DEST_PREFIX\\\", \\\"value\\\": \\\"$${dest_prefix}\\\"}]}], \\\"taskRoleArn\\\":  \\\"arn:aws:iam::$${aws_account}:role/$${ch}-$${dest_env}\\\"} \

Любая помощь приветствуется?Я пробовал много разных способов, но ничего не получается.

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Основываясь на ответе Vasiliki Siakka , я предварительно проанализировал параметр json и избежал двойных кавычек в строке json, чтобы избежать их удаления в команде ssh. Итак, решение, которое сработало для меня, выглядит следующим образом:

sshagent(credentials: ['keypair']) {

  // ch is defined is defined somewhere in the pipeline
  // aws_account is also defined somewhere in the pipeline

  def overrides = [
    containerOverrides: [
      [
        environment: [
          [
            name: "SRC_ENV",
            value: params.source_env
          ],
          [
            name: "DEST_ENV",
            value: params.destination_env
          ],
          [
            name: "SRC_PREFIX",
            value: params.source_s3_prefix
          ],
          [
            name: "DEST_PREFIX",
            value: params.destination_s3_prefix
          ]
        ],
        name: "s3-sync"
      ]
    ],
    taskRoleArn: "arn:aws:iam::${aws_account}:role/${ch}-${params.destination_env}"
  ]

  def parsed_overrides = groovy.json.JsonOutput.toJson(overrides).replace("\"", "\\\"")



  sh """
      ssh ansible@ansible-server \
      '
# Run ECS task
echo "---- Run ECS task ----"
task_id=\$(aws ecs run-task \
  --cluster cluster-${ch}-${params.destination_env} \
  --task-definition \$td_id \
  --region ${region} \
  --overrides "${parsed_overrides}" \
  --query 'tasks[0].taskArn' \
  --output text | cut -d'/' -f 2)
      '
    """
}
0 голосов
/ 13 сентября 2018

Я предлагаю вместо того, чтобы пытаться вычислить все переменные после ssh, вместо этого вы вычисляете команду shh как часть оценки сценария оболочки.

В groovy, когда вы используете двойные кавычки (одинарные или тройные)все, что следует за $, будет оценено / заменено.Таким образом, вы можете просто добавить $ перед каждой переменной, которая используется в вашем сценарии оболочки, и переменная будет оценена еще до того, как сценарий оболочки будет запущен.Вам также необходимо экранировать любые $, которые вы не хотите оценивать как часть обработки строки.

В частности, для BLOB-объекта json я предлагаю создать карту вне сценария оболочки, которая содержитпереопределяет, а затем преобразовывает эту переменную в строку json.Таким образом, вам не нужно беспокоиться об использовании правильного числа \ (хотя вы можете использовать одинарные кавычки внутри строки тройных кавычек без экранирования), и ваш файл конвейера будет более читабельным.

Вот как я бы это написал:

sshagent(credentials: ['keypair']) {

  // ch is defined is defined somewhere in the pipeline
  // aws_account is also defined somewhere in the pipeline

  def overrides = [
    containerOverrides: [
      [
        environment: [
          [
            name: "SRC_ENV",
            value: params.source_env
          ],
          [
            name: "DEST_ENV",
            value: params.destination_env
          ],
          [
            name: "SRC_PREFIX",
            value: params.source_s3_prefix
          ],
          [
            name: "DEST_PREFIX",
            value: params.destination_s3_prefix
          ]
        ],
        name: "s3-sync"
      ]
    ],
    taskRoleArn: "arn:aws:iam::${aws_account}:role/${ch}-${params.destination_env}"
  ]


  sh """
    ssh ansible@ansible-server \
    '
# Run ECS task
echo "---- Run ECS task ----"
task_id=\$(aws ecs run-task \
  --cluster cluster-${ch}-${params.destination_env} \
  --task-definition \$td_id \
  --region ${region} \
  --overrides ${groovy.json.JsonOutput.toJson(overrides)} \
  --query 'tasks[0].taskArn' \
  --output text | cut -d'/' -f 2)
    '
  """
}

Обратите внимание, что я не экранировал ни одну из переменных, которые я хочу заменить при обработке строки, и я только экранировал

task_id=\$(aws ecs run-task \

Так что aws ecs run-task ... запускается при выполнении сценария ssh (а не при оценке строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...