Ansible中如何从字典列表统计各项目user_quota总和
Ansible:按项目统计user_quota总和
我有一个字典结构的数据,需要按项目分别计算每个项目下所有用户的user_quota总和。比如blue项目的总和应为3G,red项目应为5G。
示例数据
project_dictionnary: project_blue: project_code: blue project_users: - user_name: Jhon user_quota: 1G - user_name: Peter user_quota: 2G project_red: project_code: red project_users: - user_name: Nelly user_quota: 3G - user_name: Kelly user_quota: 2G
原代码问题
我尝试了以下代码,但没有得到预期结果:
- name: "Get user_quota" set_fact: total: "{{ total|default(0)|int + item[:-1]|int }}" loop: "{{ project_dictionnary | json_query('.*.project_users[*].user_quota') }}" - name: "the user quota is:" debug: var=total
问题出在json_query('.*.project_users[*].user_quota')返回的是嵌套列表,格式为[["1G", "2G"], ["3G", "2G"]]。循环时item是每个项目的quota列表(比如["1G", "2G"]),直接对item[:-1]取子串会把整个列表当成字符串处理,导致计算错误,而且最终只会得到所有项目的总合,无法按项目区分。
解决方案
方法1:按项目遍历,逐个计算总和
遍历每个项目,对项目内的用户quota求和,同时保留单位:
- name: 按项目计算user_quota总和 set_fact: project_quota_totals: "{{ project_quota_totals | default({}) | combine({ item.value.project_code: total_quota }) }}" vars: # 提取当前项目的所有quota数值,去掉单位转整数后求和 quota_numbers: "{{ item.value.project_users | map(attribute='user_quota') | map('regex_replace', '^(\\d+)G$', '\\1') | map('int') | sum }}" total_quota: "{{ quota_numbers }}G" loop: "{{ project_dictionnary | dict2items }}" - name: 输出每个项目的quota总和 debug: var: project_quota_totals
执行后会得到结果:
project_quota_totals: blue: 3G red: 5G
方法2:用json_query结合sum(灵活计算单项目/总合)
如果只需要单个项目的总和,比如blue项目:
- name: 计算blue项目quota总和 set_fact: blue_total: "{{ (project_dictionnary | json_query('project_blue.project_users[*].user_quota') | map('regex_replace', '^(\\d+)G$', '\\1') | map('int') | sum) }}G" - name: 输出blue项目总和 debug: var=blue_total
如果需要所有项目的总合:
- name: 计算所有项目quota总合 set_fact: all_total: "{{ (project_dictionnary | json_query('*.project_users[*].user_quota') | flatten | map('regex_replace', '^(\\d+)G$', '\\1') | map('int') | sum) }}G" - name: 输出总合 debug: var=all_total
内容的提问来源于stack exchange,提问作者Kooky
相关产品推荐
相关产品推荐

