Node.js使用js-yaml解析Ansible hosts.yaml如何转换为可遍历数组
解决方案
原理说明
Ansible的Inventory YAML规范明确要求,主机组下的主机必须为键值对映射结构,而非数组。因此js-yaml默认将YAML映射解析为JS对象是符合标准的行为,不需要调整解析配置。你无需直接修改解析得到的原始结构,只需要在业务逻辑层做一次格式转换,即可同时满足遍历统计需求和Ansible兼容性要求。
实现步骤
1. 解析YAML并转换为数组格式用于业务处理
const yaml = require('js-yaml'); const fs = require('fs'); // 加载原始hosts.yaml文件 const rawYamlContent = fs.readFileSync('hosts.yaml', 'utf8'); const originalInventory = yaml.load(rawYamlContent); // 转换为你需要的数组格式,用于遍历、统计、修改配置 const processedInventory = { all: { // 转换masters组为数组 masters: Object.entries(originalInventory.all.masters).map(([hostName, hostConfig]) => { return { [hostName]: hostConfig }; }), // 转换workers组为数组 workers: Object.entries(originalInventory.all.workers).map(([hostName, hostConfig]) => { return { [hostName]: hostConfig }; }) } }; // 此时你可以直接遍历processedInventory.all.masters、processedInventory.all.workers数组, // 统计数量直接取数组length属性即可,修改配置直接操作数组内的对象即可
2. 修改完成后转换回原始结构写回文件
// 把数组格式转换回Ansible兼容的键值对结构 const inventoryToSave = { all: { masters: processedInventory.all.masters.reduce((acc, hostItem) => { const [hostName, hostConfig] = Object.entries(hostItem)[0]; acc[hostName] = hostConfig; return acc; }, {}), workers: processedInventory.all.workers.reduce((acc, hostItem) => { const [hostName, hostConfig] = Object.entries(hostItem)[0]; acc[hostName] = hostConfig; return acc; }, {}) } }; // 写回文件,indent参数指定缩进为2空格,符合Ansible常用的YAML格式规范 fs.writeFileSync('hosts.yaml', yaml.dump(inventoryToSave, { indent: 2 }), 'utf8');
通用优化
如果你的主机组是动态的,不止masters和workers两类,可以用通用转换函数适配所有组:
// 原始结构转数组结构 function convertToArrayFormat(rawInventory) { return { all: Object.fromEntries( Object.entries(rawInventory.all).map(([groupName, hostMap]) => [ groupName, Object.entries(hostMap).map(([hostName, hostConfig]) => ({ [hostName]: hostConfig })) ]) ) }; } // 数组结构转原始结构 function convertToRawFormat(arrayInventory) { return { all: Object.fromEntries( Object.entries(arrayInventory.all).map(([groupName, hostArr]) => [ groupName, hostArr.reduce((acc, hostItem) => { const [hostName, hostConfig] = Object.entries(hostItem)[0]; acc[hostName] = hostConfig; return acc; }, {}) ]) ) }; }
内容的提问来源于stack exchange,提问作者Dreamystify
相关产品推荐
相关产品推荐

