ansible.builtin.script inventory – 执行返回 JSON 的清单脚本
注意
此清单插件是 ansible-core
的一部分,包含在所有 Ansible 安装中。在大多数情况下,您可以使用简短的插件名称 script
。但是,我们建议您使用 完全限定的集合名称 (FQCN) ansible.builtin.script
,以方便链接到插件文档并避免与可能具有相同清单插件名称的其他集合发生冲突。
概要
提供的源代码必须是返回 Ansible 清单 JSON 的可执行文件
源代码必须接受
--list
和--host <hostname>
作为参数。--host
仅在没有_meta
键时才会使用。这是一种性能优化,因为否则脚本将被额外调用一次,针对每个主机。
参数
参数 |
注释 |
---|---|
即使脚本成功,也切换显示 stderr 选项
配置
|
备注
注意
在配置中默认启用。
插件不缓存结果,因为外部清单脚本负责自己的缓存。
要编写自己的清单脚本,请参阅 (开发动态清单 来自文档网站)。
要找到曾经是代码发布的一部分的脚本,请访问 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
提示
每个条目类型的配置条目具有从低到高的优先级顺序。例如,列表中较低的变量将覆盖列表中较高的变量。