ansible.builtin.script 库存 – 执行返回 JSON 的库存脚本
注意
此库存插件是 ansible-core
的一部分,包含在所有 Ansible 安装中。在大多数情况下,您可以使用简短的插件名称 script
。但是,我们建议您使用 完全限定集合名称 (FQCN) ansible.builtin.script
以便轻松链接到插件文档并避免与可能具有相同库存插件名称的其他集合发生冲突。
摘要
提供的源代码必须是返回 Ansible 库存 JSON 的可执行文件
源代码必须接受
--list
和--host <hostname>
作为参数。只有在不存在_meta
键时才会使用--host
。这是一种性能优化,否则脚本将额外调用一次才能获取每个主机的信息。
参数
参数 |
注释 |
---|---|
即使脚本成功,也切换是否显示标准错误输出 选项
配置
|
备注
注意
默认情况下在配置中启用。
插件不会缓存结果,因为外部库存脚本负责自己的缓存。
要编写您自己的库存脚本,请参阅(文档站点中的 开发动态库存)。
要查找过去作为代码版本一部分的脚本,请访问 https://github.com/ansible-community/contrib-scripts/。
从 2.19 开始,使用目录作为库存源默认情况下不再忽略 .ini 文件,但您仍然可以更新配置以执行此操作。
示例
# fmt: code
### simple bash script
#!/usr/bin/env bash
if [ "$1" == "--list" ]; then
cat<<EOF
{
"bash_hosts": {
"hosts": [
"myhost.domain.com",
"myhost2.domain.com"
],
"vars": {
"host_test": "test-value"
}
},
"_meta": {
"hostvars": {
"myhost.domain.com": {
"host_specific_test_var": "test-value"
}
}
}
}
EOF
elif [ "$1" == "--host" ]; then
# this should not normally be called by Ansible as we return _meta above
if [ "$2" == "myhost.domain.com" ]; then
echo '{"_meta": {hostvars": {"myhost.domain.com": {"host_specific-test_var": "test-value"}}}}'
else
echo '{"_meta": {hostvars": {}}}'
fi
else
echo "Invalid option: use --list or --host <hostname>"
exit 1
fi
### python example with ini config
#!/usr/bin/env python
"""
# ansible_inventory.py
"""
import argparse
import json
import os.path
import sys
from configparser import ConfigParser
from inventories.custom import MyInventoryAPI
def load_config() -> ConfigParser:
cp = ConfigParser()
config_file = os.path.expanduser("~/.config/ansible_inventory_script.cfg")
cp.read(config_file)
if not cp.has_option('DEFAULT', 'namespace'):
raise ValueError("Missing configuration option: DEFAULT -> namespace")
return cp
def get_api_data(namespace: str, pretty=False) -> str:
"""
:param namespace: parameter for our custom api
:param pretty: Human redable JSON vs machine readable
:return: JSON string
"""
found_data = list(MyInventoryAPI(namespace))
hostvars = {}
data = { '_meta': { 'hostvars': {}},}
groups = found_data['groups'].keys()
for group in groups:
groups[group]['hosts'] = found_data[groups].get('host_list', [])
if group not in data:
data[group] = {}
data[group]['hosts'] = found_data[groups].get('host_list', [])
data[group]['vars'] = found_data[groups].get('info', [])
data[group]['children'] = found_data[group].get('subgroups', [])
for host_data in found_data['hosts']:
for name in host_data.items():
# turn info into vars
data['_meta'][name] = found_data[name].get('info', {})
# set ansible_host if possible
if 'address' in found_data[name]:
data[name]['_meta']['ansible_host'] = found_data[name]['address']
data['_meta']['hostvars'] = hostvars
return json.dumps(data, indent=pretty)
if __name__ == '__main__':
arg_parser = argparse.ArgumentParser( description=__doc__, prog=__file__)
arg_parser.add_argument('--pretty', action='store_true', default=False, help="Pretty JSON")
mandatory_options = arg_parser.add_mutually_exclusive_group()
mandatory_options.add_argument('--list', action='store', nargs="*", help="Get inventory JSON from our API")
mandatory_options.add_argument('--host', action='store',
help="Get variables for specific host, not used but kept for compatibility")
try:
config = load_config()
namespace = config.get('DEFAULT', 'namespace')
args = arg_parser.parse_args()
if args.host:
print('{"_meta":{}}')
sys.stderr.write('This script already provides _meta via --list, so this option is really ignored')
elif len(args.list) >= 0:
print(get_api_data(namespace, args.pretty))
else:
raise ValueError("Valid options are --list or --host <HOSTNAME>")
except ValueError:
raise
提示
每个条目类型的配置条目具有从低到高的优先级顺序。例如,列表中较低的变量将覆盖较高的变量。