如何按列表成员的name属性对Ansible主机列表进行版本排序
问题:Ansible中按name字段对主机列表实现自然排序
我尝试用以下Ansible代码按name字段对主机列表排序:
--- - hosts: localhost vars: hosts: - name: host2 uptime: 1d - name: host10 uptime: 45d - name: host1 uptime: 3m tasks: - name: version sort host list debug: #var: hosts | community.general.version_sort #var: hosts | dictsort(false, 'value') var: hosts | sort(attribute='name')
可以看到排序结果不符合预期(host2应该排在host10之前):
TASK [version sort host list] ************************************* ok: [localhost] => { "hosts | sort(attribute='name')": [ { "name": "host1", "uptime": "3m" }, { "name": "host10", <------- "uptime": "45d" }, { "name": "host2", "uptime": "1d" } ] }
我查过version_sort过滤器,但它不支持按属性排序,而且当前无法修改主机名格式,求其他解决思路。
解决方案:结合version_sort与extract实现自然排序
感谢@Vladimir Botka提供的方案,我整合了其中一种思路,编写了如下剧本(新增FQDN主机名让场景更复杂,方案依然有效):
- hosts: localhost vars: hosts: - {name: host2.example.com, uptime: 1d} - {name: host10.example.com, uptime: 45d} - {name: host1.example.com, uptime: 3m} - {name: host3.example.com, uptime: 3m} - {name: host15.example.com, uptime: 45d} - {name: host20.example.com, uptime: 45d} tasks: # - debug: # msg: # - "index: {{ hosts | map(attribute='name') | community.general.version_sort }}" # - "host_indexed: {{ dict(hosts|json_query('[].[name,@]')) }}" # - "solution: {{ (hosts | map(attribute='name') | community.general.version_sort) | map('extract', dict(hosts|json_query('[].[name,@]'))) }}" - debug: var: (hosts | map(attribute='name') | community.general.version_sort) | map('extract', dict(hosts|json_query('[].[name,@]')))
执行结果如下:
PLAY [localhost] ***************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************** ok: [localhost] TASK [debug] ********************************************************************************************************************************************* [WARNING]: Collection community.general does not support Ansible version 2.14.17 ok: [localhost] => { "(hosts | map(attribute='name') | community.general.version_sort) | map('extract', dict(hosts|json_query('[].[name,@]')))": [ { "name": "host1.example.com", "uptime": "3m" }, { "name": "host2.example.com", "uptime": "1d" }, { "name": "host3.example.com", "uptime": "3m" }, { "name": "host10.example.com", "uptime": "45d" }, { "name": "host15.example.com", "uptime": "45d" }, { "name": "host20.example.com", "uptime": "45d" } ] } PLAY RECAP *********************************************************************************************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
内容的提问来源于stack exchange,提问作者zagpoint
相关产品推荐
相关产品推荐

