在Ansible中使用json_query对复杂的JSON进行排序

mm5n2pyu  于 2023-08-08  发布在  其他
关注(0)|答案(1)|浏览(200)

我在使用Ansible时遇到了一个令人沮丧的问题,并试图解析一个复杂的JSON对象。
我需要找到作为根文件系统挂载的设备的物理卷、逻辑卷、磁盘名和分区名。我已经从ansible_lvm事实中获得了物理和逻辑卷名。
在默认的gathering_facts步骤中,Ansible还将有关系统磁盘的事实收集到名为ansible_devices的字典变量中:

{
    "ansible_devices": {
        "dm-0": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [
                    "dm-name-ubuntu--vg-ubuntu--lv",
                    "dm-uuid-LVM-4s1K7fFeMXzoaijoeifajoiejoifjSi5DMhqUB2o9jvEJ5IOSIFE0902djfoiGhXaLL10sR"
                ],
                "labels": [],
                "masters": [],
                "uuids": [
                    "e9a5105b-9a0d-46ea-a0f39-a983ur9apdo98fr3"
                ]
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "",
            "sectors": "955801600",
            "sectorsize": "512",
            "size": "455.76 GB",
            "support_discard": "512",
            "vendor": null,
            "virtual": 1
        },
        "loop0": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "129936",
            "sectorsize": "512",
            "size": "63.45 MB",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop1": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "129944",
            "sectorsize": "512",
            "size": "63.45 MB",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop2": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "188072",
            "sectorsize": "512",
            "size": "91.83 MB",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop3": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "109072",
            "sectorsize": "512",
            "size": "53.26 MB",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop4": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "109072",
            "sectorsize": "512",
            "size": "53.26 MB",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop5": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "137712",
            "sectorsize": "512",
            "size": "67.24 MB",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop6": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "0",
            "sectorsize": "512",
            "size": "0.00 Bytes",
            "support_discard": "4096",
            "vendor": null,
            "virtual": 1
        },
        "loop7": {
            "holders": [],
            "host": "",
            "links": {
                "ids": [],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": null,
            "partitions": {},
            "removable": "0",
            "rotational": "1",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "mq-deadline",
            "sectors": "0",
            "sectorsize": "512",
            "size": "0.00 Bytes",
            "support_discard": "0",
            "vendor": null,
            "virtual": 1
        },
        "nvme0n1": {
            "holders": [],
            "host": "Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller SM981/PM981/PM983",
            "links": {
                "ids": [
                    "nvme-Samsung_SSD_970_EVO_Plus_500GB_S4EVNX0W303511J",
                    "nvme-eui.0025385331b1d473"
                ],
                "labels": [],
                "masters": [],
                "uuids": []
            },
            "model": "Samsung SSD 970 EVO Plus 500GB",
            "partitions": {
                "nvme0n1p1": {
                    "holders": [],
                    "links": {
                        "ids": [
                            "nvme-Samsung_SSD_970_EVO_Plus_500GB_S4EVNX0W303511J-part1",
                            "nvme-eui.0025385331b1d473-part1"
                        ],
                        "labels": [],
                        "masters": [],
                        "uuids": [
                            "F0A4-B4A1"
                        ]
                    },
                    "sectors": "1101824",
                    "sectorsize": 512,
                    "size": "538.00 MB",
                    "start": "2048",
                    "uuid": "F0A4-B4A1"
                },
                "nvme0n1p2": {
                    "holders": [],
                    "links": {
                        "ids": [
                            "nvme-Samsung_SSD_970_EVO_Plus_500GB_S4EVNX0W303511J-part2",
                            "nvme-eui.0025385331b1d473-part2"
                        ],
                        "labels": [],
                        "masters": [],
                        "uuids": [
                            "c8811628-4d6d-4402-bba2-c0ff74015361"
                        ]
                    },
                    "sectors": "1857536",
                    "sectorsize": 512,
                    "size": "907.00 MB",
                    "start": "1103872",
                    "uuid": "c8811628-4d6d-4402-bba2-c0ff74015361"
                },
                "nvme0n1p3": {
                    "holders": [
                        "ubuntu--vg-ubuntu--lv"
                    ],
                    "links": {
                        "ids": [
                            "lvm-pv-uuid-0FPssp-8lMn-Q3cM-nkiK-lXs5-1aCQ-G2bbLd",
                            "nvme-Samsung_SSD_970_EVO_Plus_500GB_S4EVNX0W303511J-part3",
                            "nvme-eui.0025385331b1d473-part3"
                        ],
                        "labels": [],
                        "masters": [
                            "dm-0"
                        ],
                        "uuids": []
                    },
                    "sectors": "973811727",
                    "sectorsize": 512,
                    "size": "464.35 GB",
                    "start": "2961408",
                    "uuid": null
                }
            },
            "removable": "0",
            "rotational": "0",
            "sas_address": null,
            "sas_device_handle": null,
            "scheduler_mode": "none",
            "sectors": "976773168",
            "sectorsize": "512",
            "serial": "S4EVNX0W303511J",
            "size": "465.76 GB",
            "support_discard": "512",
            "vendor": null,
            "virtual": 1
        }
    }
}

字符串
在该变量中,我可以看到LVM“持有”的磁盘及其分区,但我无法找出如何过滤单个字典项。
我想找出partitions值为holders==["ubuntu--vg-ubuntu--lv"]的单个设备对象,但无法找出正确的语法。
我试过json_queryselectattr和其他一些过滤器与dict2items的组合,但我认为我遗漏了一些东西。
关于json_query的文档似乎相当稀疏,而且它与我从常规jq实用程序中了解到的内容并不完全匹配。
如有任何帮助,将不胜感激!

t1rydlwq

t1rydlwq1#

json_query过滤器不使用jq;它使用jmespathdocumentation对此非常清楚:
在使用此过滤器之前,必须在Ansible控制器上手动安装jmespath依赖项。这个过滤器是基于jmespath构建的,您可以使用相同的语法。例如,请参见jmespath examples
如果您通过该链接访问jmespath.org,您将找到大量文档和示例。
话虽如此,我认为jmespath不太适合您正在处理的数据类型,因为您实际上具有任意的嵌套级别,并且jmespath似乎没有与xpath的//操作等效的操作。
有时一个更简单的解决方案是在filter_plugins目录中放置一个自定义过滤器。

def find_holder(v, holder):
    for devname, devdata in v.items():
        if holder in devdata["holders"]:
            return devname, devdata

        if "partitions" in devdata:
            devname, devdata = find_holder(devdata["partitions"], holder)
            if devname is not None:
                return devname, devdata

    return None, None

class FilterModule:
    def filters(self):
        return {
            "find_holder": find_holder,
        }

字符串
然后在你的剧本中使用它:

- debug:
    msg: "{{ ansible_devices|find_holder('ubuntu--vg-ubuntu--lv') }}"

相关问题