Ansible 中有多个 json_query?
Multiple json_query in Ansible?
我有以下 yaml 文件。
resources:
- apiVersion: v1
kind: Deployment
metadata:
labels:
app: test
name: test-cluster-operator
namespace: destiny001
spec:
selector:
matchLabels:
name: test-cluster-operator
test.io/kind: cluster-operator
strategy:
type: Recreate
template:
metadata:
labels:
name: test-cluster-operator
test.io/kind: cluster-operator
spec:
containers:
- args:
- /path/test/bin/cluster_operator_run.sh
env:
- name: MY_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthy
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 1
name: test-cluster-operator
readinessProbe:
failureThreshold: 3
httpGet:
path: /ready
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: '1'
memory: 256Mi
requests:
cpu: 200m
memory: 256Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/data
name: data-cluster-operator
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: test-cluster-operator
serviceAccountName: test-cluster-operator
terminationGracePeriodSeconds: 30
volumes:
- name: data-cluster-operator
persistentVolumeClaim:
claimName: data-cluster-operator
我正在尝试获取名为 MY_NAMESPACE 的环境变量的值。
这是我在 Ansible 中尝试进入 env 树路径的方法。
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | json_query(\"containers[?name=='test-cluster-operator'].env\") }}"
- name: "debug"
debug:
msg: "{{ myresult }}"
这会生成一个空列表,但是第一个 json_query 效果很好。
在这种情况下如何正确使用 json_query?
我可以只用一个 json_query 来实现吗?
编辑:
我似乎更接近解决方案,但结果是一个列表而不是字符串,我觉得这很烦人。
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | json_query(\"[].containers[?name=='test-cluster-operator']\") | json_query(\"[].env[?name=='MY_NAMESPACE'].name\") }}"
这会打印 - - MY_NAMESPACE
而不仅仅是 MY_NAMESPACE
。
我是否必须在 json_query 之后每次都使用 first
过滤器?我确定只有一个 containers
元素。我不明白为什么 json_query returns 一个列表。
这终于奏效了,但不知道这样做是否正确。
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | first | json_query(\"containers[?name=='test-cluster-operator']\") | first | json_query(\"env[?name=='MY_NAMESPACE'].valueFrom \") | first }}"
json_query 使用 jmespath 并且 jmespath 总是 returns 一个列表。这就是为什么您的第一个示例不起作用的原因。第一个查询 return 是一个列表,但第二个查询试图查询一个键。您已在第二个中使用 [].
更正了这一点
您还缺少 jmespath 管道表达式:|
,它的使用与您预期的差不多 - 第一个查询的结果可以通过管道传输到新的查询中。请注意,这与使用相同字符的 ansible 过滤器是分开的。
这个查询:
resources[?metadata.name=='test-cluster-operator'].spec.template.spec | [].containers[?name=='test-cluster-operator'][].env[].valueFrom
应该给你以下输出:
[
{
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "metadata.namespace"
}
}
]
您的任务应如下所示:
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec | [].containers[?name=='test-cluster-operator'][].env[].valueFrom\") | first }}"
要回答您的其他问题,是的,您需要 first
过滤器。如前所述,jmespath 将始终 return 一个列表,因此如果您只想要一个键的值,则需要将其拉出。
我有以下 yaml 文件。
resources:
- apiVersion: v1
kind: Deployment
metadata:
labels:
app: test
name: test-cluster-operator
namespace: destiny001
spec:
selector:
matchLabels:
name: test-cluster-operator
test.io/kind: cluster-operator
strategy:
type: Recreate
template:
metadata:
labels:
name: test-cluster-operator
test.io/kind: cluster-operator
spec:
containers:
- args:
- /path/test/bin/cluster_operator_run.sh
env:
- name: MY_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthy
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 1
name: test-cluster-operator
readinessProbe:
failureThreshold: 3
httpGet:
path: /ready
port: 8080
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: '1'
memory: 256Mi
requests:
cpu: 200m
memory: 256Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/data
name: data-cluster-operator
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: test-cluster-operator
serviceAccountName: test-cluster-operator
terminationGracePeriodSeconds: 30
volumes:
- name: data-cluster-operator
persistentVolumeClaim:
claimName: data-cluster-operator
我正在尝试获取名为 MY_NAMESPACE 的环境变量的值。 这是我在 Ansible 中尝试进入 env 树路径的方法。
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | json_query(\"containers[?name=='test-cluster-operator'].env\") }}"
- name: "debug"
debug:
msg: "{{ myresult }}"
这会生成一个空列表,但是第一个 json_query 效果很好。
在这种情况下如何正确使用 json_query? 我可以只用一个 json_query 来实现吗?
编辑: 我似乎更接近解决方案,但结果是一个列表而不是字符串,我觉得这很烦人。
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | json_query(\"[].containers[?name=='test-cluster-operator']\") | json_query(\"[].env[?name=='MY_NAMESPACE'].name\") }}"
这会打印 - - MY_NAMESPACE
而不仅仅是 MY_NAMESPACE
。
我是否必须在 json_query 之后每次都使用 first
过滤器?我确定只有一个 containers
元素。我不明白为什么 json_query returns 一个列表。
这终于奏效了,但不知道这样做是否正确。
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | first | json_query(\"containers[?name=='test-cluster-operator']\") | first | json_query(\"env[?name=='MY_NAMESPACE'].valueFrom \") | first }}"
json_query 使用 jmespath 并且 jmespath 总是 returns 一个列表。这就是为什么您的第一个示例不起作用的原因。第一个查询 return 是一个列表,但第二个查询试图查询一个键。您已在第二个中使用 [].
您还缺少 jmespath 管道表达式:|
,它的使用与您预期的差不多 - 第一个查询的结果可以通过管道传输到新的查询中。请注意,这与使用相同字符的 ansible 过滤器是分开的。
这个查询:
resources[?metadata.name=='test-cluster-operator'].spec.template.spec | [].containers[?name=='test-cluster-operator'][].env[].valueFrom
应该给你以下输出:
[
{
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "metadata.namespace"
}
}
]
您的任务应如下所示:
- name: "set test fact"
set_fact:
myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec | [].containers[?name=='test-cluster-operator'][].env[].valueFrom\") | first }}"
要回答您的其他问题,是的,您需要 first
过滤器。如前所述,jmespath 将始终 return 一个列表,因此如果您只想要一个键的值,则需要将其拉出。