我使用python访问foreman API来收集foreman所知道的所有主机的一些事实。不幸的是,v1 foreman API中没有get all hosts facts(或类似的东西),所以我必须遍历所有主机并获取信息。这样做让我遇到了一个麻烦。对给定主机的每次调用都会返回一个JSON对象,如下所示:
{
"host1.com": {
"apt_update_last_success": "1452187711",
"architecture": "amd64",
"augeasversion": "1.2.0",
"bios_release_date": "06/03/2015",
"bios_vendor": "Dell Inc."
}
}
这很好,当我附加下一个主机的信息时,问题就出现了。然后我得到一个json文件,它看起来像这样:
^{pr2}$下面是执行此操作的代码:
for i in hosts_data:
log.info("Gathering host facts for host: {}".format(i['host']['name']))
try:
facts = requests.get(foreman_host+api+"hosts/{}/facts".format(i['host']['id']), auth=(username, password))
if hosts.status_code != 200:
log.error("Unable to connect to Foreman! Got retcode '{}' and error message '{}'"
.format(hosts.status_code, hosts.text))
sys.exit(1)
except requests.exceptions.RequestException as e:
log.error(e)
facts_data = json.loads(facts.text)
log.debug(facts_data)
with open(results_file, 'a') as f:
f.write(json.dumps(facts_data, sort_keys=True, indent=4))
我需要文件的格式如下:
{
"host1.com": {
"apt_update_last_success": "1452187711",
"architecture": "amd64",
"augeasversion": "1.2.0",
"bios_release_date": "06/03/2015",
"bios_vendor": "Dell Inc."
},
"host2.com": {
"apt_update_last_success": "1452703454",
"architecture": "amd64",
"augeasversion": "1.2.0",
"bios_release_date": "06/03/2015",
"bios_vendor": "Dell Inc."
}
}
为了安全性/一致性,您需要加载旧数据,对其进行修改,然后将其写回。在
将当前
with
和write
更改为:注意:如果可能的话,您希望使用pault's answer来最小化不必要的I/O,如果数据检索应该是逐段进行的,并且在每个项变得可用时立即更新,那么就应该这样做。在
请注意,最不安全的方法是找到后面的大括号,删除它,然后写出一个逗号,后跟新的JSON(从JSON表示中删除前导的大括号)。它的I/O密集度要低得多,但也不太安全,不会清除重复项,不会对主机进行排序,根本不验证输入文件,等等,所以不要这样做。在
最好将所有数据汇编成一个dict,然后一次写出,而不是每次都在循环中。在
不要在循环中写入json,而是将数据插入具有正确结构的
dict
。然后在循环结束时将dict写入json。在这假设您的数据集适合内存。在
相关问题 更多 >
编程相关推荐