我的var文件中有以下变量:
repo_type:
hosted:
data:
- name: hosted_repo1
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: hosted_repo2
online: true
storage:
blobstarage: default
write_policy: allow_once
proxy:
data:
- name: proxy_repo1
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: proxy_repo2
online: true
storage:
blobstarage: default
write_policy: allow_once
group:
data:
- name: group_repo1
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: group_repo2
online: true
storage:
blobstarage: default
write_policy: allow_once
我想配置一个任务来循环(托管,代理和组)和主体在数据字典。
任务如下:
- name: Create pypi hosted Repos
uri:
url: "{{ nexus_api_scheme }}://{{ nexus_api_hostname }}:{{ nexus_api_port }}
{{ nexus_api_context_path }}{{ nexus_rest_api_endpoint }}/repositories/pypi/{{ item.key}}"
user: "{{ nexus_api_user }}"
password: "{{ nexus_default_admin_password }}"
headers:
accept: "application/json"
Content-Type: "application/json"
body_format: json
method: POST
force_basic_auth: yes
validate_certs: "{{ nexus_api_validate_certs }}"
body: "{{ item }}"
status_code: 201
no_log: no
with_dict: "{{ repo_type}}"
我试过with_items
,with_dict
和with_nested
,但没有任何帮助。
任务包含一个未定义变量的选项。此错误是:'dict object'没有属性'data'
任何帮助将不胜感激!
如果您的目标是将data
键的内容作为一个平面列表循环遍历,那么您可以这样做:
- debug:
msg: "repo {{ item.name }} write_policy {{ item.storage.write_policy }}"
loop_control:
label: "{{ item.name }}"
loop: "{{ repo_type | json_query('*.data[]') }}"
使用JMESPath表达式从中获取data
键顶级字典,然后将结果嵌套列表平面化。在换句话说,它将原始结构转换为:
- name: hosted_repo1
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: hosted_repo2
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: proxy_repo1
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: proxy_repo2
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: group_repo1
online: true
storage:
blobstarage: default
write_policy: allow_once
- name: group_repo2
online: true
storage:
blobstarage: default
write_policy: allow_once
使用示例数据运行时,将产生如下输出:
TASK [debug] *********************************************************************************************************
ok: [localhost] => (item=hosted_repo1) => {
"msg": "repo hosted_repo1 write_policy allow_once"
}
ok: [localhost] => (item=hosted_repo2) => {
"msg": "repo hosted_repo2 write_policy allow_once"
}
ok: [localhost] => (item=proxy_repo1) => {
"msg": "repo proxy_repo1 write_policy allow_once"
}
ok: [localhost] => (item=proxy_repo2) => {
"msg": "repo proxy_repo2 write_policy allow_once"
}
ok: [localhost] => (item=group_repo1) => {
"msg": "repo group_repo1 write_policy allow_once"
}
ok: [localhost] => (item=group_repo2) => {
"msg": "repo group_repo2 write_policy allow_once"
}
如果你想做其他事情,请更新你的问题它清楚地显示了您期望的值循环。
正如@larsk所报道的,你实际上没有设法解释清楚你是如何试图循环你的数据和你的api调用实际上是什么。
但是这次你很幸运,因为我在Nexus上搞砸了很多(我想我实际上认识那些变量名和整体任务布局)
Nexus RepositoryPOST /v1/repositories/pypi/[hosted|proxy|group]
API端点期望对data
中的每个repos进行一次调用。要实现您的需求,您需要遍历repo_type
中的键以选择适当的端点,然后再次遍历data
中的每个元素以发送要创建的repo定义。
这实际上是可以在你的循环中结合dict2items
和subelements
过滤器,就像下面的剧本(没有直接测试)。
转换的基础如下:
- 使用
dict2items
将您的字典转换为键/值列表,例如(缩短示例)- key: hosted value: data: - <repo definition 1> - <repo definition 2> [...]
- 使用
subelements
过滤器将每个顶部元素与value.data
中的每个元素组合在一起,例如:- # <- This is the entry for first repo i.e. `item` in your loop - key: hosted # <- this is the start of the corresponding top element i.e. `item.0` in your loop value: data: - <repo definition 1> - <repo definition 2> - <repo definition 1> # <- this is the sub-element i.e. `item.1` in your loop - # <- this is the entry for second repo - key: hosted value: data: - <repo definition 1> - <repo definition 2> - <repo definition 2> [...]
根据您的评论和我的经验,我使用to_json
过滤器在我的示例中添加了repo定义的显式json序列化。
把这些放在一起就得到:
- name: Create pypi hosted Repos
uri:
url: "{{ nexus_api_scheme }}://{{ nexus_api_hostname }}:{{ nexus_api_port }}
{{ nexus_api_context_path }}{{ nexus_rest_api_endpoint }}/repositories/pypi/{{ item.0.key }}"
user: "{{ nexus_api_user }}"
password: "{{ nexus_default_admin_password }}"
headers:
accept: "application/json"
Content-Type: "application/json"
body_format: json
method: POST
force_basic_auth: yes
validate_certs: "{{ nexus_api_validate_certs }}"
body: "{{ item.1 | to_json }}"
status_code: 201
no_log: no
loop: "{{ repo_type | dict2items | subelements('value.data') }}"