在 Ansible 中通过管道传输到 json_query 没有显示任何结果?

问题描述 投票:0回答:1

我有一个 Ansible 剧本,其中包括在我的集群服务器上通过

cert-manager
生成 Let's Encrypt 证书。

但是我必须等到证书准备好后,才能继续执行剧本中的下一个任务。

这给了我以下 Ansible 任务:

- name: Get TLS certificate secret and wait until ready
  command:
    cmd: 'kubectl get certificate tls-rancher-ingress -n cattle-system -ojson'
  register: certificate_result
  changed_when: (certificate_result.stdout | json_query('status.conditions[0].status') == '"True"')
  retries: 10
  delay: 30

在上面的代码中,证书名为

tls-rancher-ingress
,我通过调用
kubectl
获取有关证书的一般信息。输出以 JSON 形式呈现。

kubectl
命令的输出(稍微匿名)采用以下形式:

{
        "apiVersion": "cert-manager.io/v1",
        "kind": "Certificate",
        "metadata": {
            "creationTimestamp": "2024-05-27T23:19:38Z",
            "generation": 2,
            "name": "tls-rancher-ingress",
            "namespace": "cattle-system",
            "resourceVersion": "2331753",
            "uid": "30b816cd-f548-4bf7-90d2-47a0406cdbb1"
        },
        "spec": {
            "commonName": "rancher.example.com",
            "dnsNames": [
                "rancher.example.com"
            ],
            "issuerRef": {
                "kind": "ClusterIssuer",
                "name": "letsencrypt-prod"
            },
            "secretName": "tls-rancher-ingress"
        },
        "status": {
            "conditions": [
                {
                    "lastTransitionTime": "2024-05-28T00:38:38Z",
                    "message": "Certificate is up to date and has not expired",
                    "observedGeneration": 2,
                    "reason": "Ready",
                    "status": "True",
                    "type": "Ready"
                }
            ],
            "notAfter": "2024-08-25T23:38:35Z",
            "notBefore": "2024-05-27T23:38:36Z",
            "renewalTime": "2024-07-26T23:38:35Z",
            "revision": 2
        }
    }

但我对整个 JSON 对象不感兴趣,而只对路径

status.conditions[0].status
等于
"True"
感兴趣。

我想我可以使用管道过滤器将

certificate_result.stdout
发送到
json_query("status.conditions[0].status")
,然后得到响应,即
"True"
"False"

使用任务悬停来调试

change_when
行会显示
json_query
返回空字符串?

我使用以下任务进行调试:

- name: Debug changed_when
  debug:
    msg: "DEBUG: {{ certificate_result.stdout | community.general.json_query('status.conditions[0].status') }}"

我使用单引号还是双引号封装字符串并不重要。

有没有人可以解释一下这是怎么回事?

是否因为

stdout
没有被视为 JSON 对象,如果是这样:将其发送到 json_query 的正确方法是什么?

供参考:

json_query
community.general
集合的一部分,已安装在我运行 Ansible playbook 的位置。

json ansible json-query
1个回答
0
投票

经过一番搜索后,我成功了。

使用的过滤器是

from_json
,这让我有点困惑。

因为虽然输出的结构是 JSON 对象,但

certificate_result.stdout
的输出将被视为字符串,因此我必须使用
to_json
将其转换为可查询的 JSON 对象。

但我显然有点……倒退了?

因此正确的命令是:

not (certificate_result.stdout | from_json | json_query("status.conditions[0].status") == "True")

整个任务如下:

- name: Get TLS certificate secret and wait until ready
  command:
    cmd: 'kubectl get certificate tls-rancher-ingress -n cattle-system -ojson'
  register: certificate_result
  until: certificate_result.stdout | from_json | json_query("status.conditions[0].status") == "True"

  retries: 10
  delay: 30
  changed_when: false

快速解释正在发生的事情:

kubectl
命令每 30 秒调用一次,将其内容输出为 JSON 对象。

并希望任务循环直到查询路径

status.conditions[0].status
的结果为真。

如果查询在第 10 次迭代后未返回 true,则任务将失败,这与任务由于 30 秒中断而在 300 秒后超时相同。

changed_when
只是ansible的一个标志,用于告知此任务是否更新了任何值,但事实并非如此,因此它应该始终返回值“false”。

© www.soinside.com 2019 - 2024. All rights reserved.