【问题标题】:How to properly use jq in ansible shell tasks如何在 ansible shell 任务中正确使用 jq
【发布时间】:2019-07-25 22:48:27
【问题描述】:

我正在尝试在 ansible shell 任务中使用 yq/jq。

我的任务采取了几种不同的形式,但到目前为止都没有奏效。我试过多行和单行。

这是我要运行的任务。我以某种方式弄错了引号,并且无法弄清楚。

这里有一些简单的 yaml - simple-service-test.yaml

---
apiVersion: extensions/v1beta1
kind: Deployment
spec:
  template:
    spec:
      containers:
        -
          args:
            - proxy
            - "--statusPort"
            - "15020"
            - "--applicationPorts"
            - "2525"

myjq.txt 的内容

.spec.template.spec.containers[0].args as $myarray | $myarray | length as $mylength | $myarray[($mylength - 1)] |= $portVal

我的测试 ansible 剧本

  ---
- name: Test yq shell
  hosts: localhost 

  tasks:
  - name: Run yq
    shell: yq --arg portVal "8443" -f {{ playbook_dir }}/myjq.txt simple-service-test.yaml > output.txt

可以运行同一文件夹中的所有文件,如 ansible-playbook playbook.yml 当我在本地使用 ansible 2.3 或 2.7 运行它时,它可以工作并输出正确的内容。当我在构建中运行相同的东西时,ansible 调用 yq 我得到jq: jv.c:199: jvp_array_write: Assertion `i >= 0' failed.

【问题讨论】:

  • 错误信息是什么?
  • 在解决这个问题之前,我们需要有足够的信息自己产生同样的问题。现在,如果您的剧本中没有其他内容,此代码将无法运行;你能生成一本任何人都可以使用的剧本吗?这样,这里的任何人都可以测试他们提出的解决方案是否真的解决了您的问题。
  • 我添加了一个剧本并更改了运行 yq 的命令,如上所示。还有一个名为 myjq.txt 的文件,其中包含我要应用的过滤器,以及一个简单的测试 yaml。基本上,我只想在“applicationPorts”之后更改值

标签: shell ansible jq


【解决方案1】:

片段

--arg portVal "{{ .Values.global.aService.inner_port }}"

在几个方面看起来是错误的。

首先,不能简单地传入 jq 程序片段 例如.Values.global_service.inner.port 通过命令行。如果您想要动态查找,您可以使用路径的数组表示,例如["Values","global_service","inner","port"]。或者您可以通过编程将路径的字符串表示形式转换为数组表示形式。

其次,如果您确实想传入除字符串以外的 JSON 值,使用--argjson 比使用--arg 更好。

最后,大括号 ({{...}}) 的重复看起来好像您正在以一种不愉快的方式将 ansible 魔法与 yq/jq 语法混合在一起。

如果您可以发布 yq 看到的输入,或者至少发布相关的 YAML 或 JSON 片段,这可能会有所帮助。

【讨论】:

  • 我试图使用 ansible 变量,但不正确。我修复了 Vlad 指出的问题,现在我在构建时获得了正确的端口值。
【解决方案2】:

.Values”不是有效的 Ansible 变量名。引用自Creating valid variable names

变量名应该是字母、数字和下划线。变量应始终以字母开头。

下面词典的展开

"{{ .Values.global.aService.inner_port }}"

必须失败

fatal: [localhost]: FAILED! => {"msg": "template error while templating string: unexpected '.'. String: {{ .Values.global.aService.inner_port }}"}

(运行字符串中可能有其他问题)

【讨论】:

  • 感谢弗拉德,我修复了变量引用并编辑了我的问题以反映这一点。
【解决方案3】:

我终于找到了。 kube-inject 的输出将“---”放在输出的末尾。当我删除它时,上面的断言错误就消失了。所以我想我需要先运行sed -i '$ d' simple-service-test.yaml,然后再针对此内容运行 yq。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-10
    • 2021-12-31
    • 1970-01-01
    • 2016-03-17
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多