Ansible Python动态清单脚本AttributeError报错解决及hostvars获取咨询
Ansible 自定义动态清单脚本问题修复
错误根因及修复点
当前代码报错及功能异常由以下几个问题导致:
- 变量名不匹配:
read_cli_args方法将解析后的命令行参数存储到self.args(末尾带s),但__init__方法中调用时写为self.arg(末尾无s),直接触发属性不存在的报错。 - 命令行参数不符合规范:Ansible 动态清单要求的单主机查询参数为
--host,代码中错误定义为--hosts(多了末尾s),会导致单主机查询功能失效。 - 输出语法错误:JSON 输出代码错误使用冒号
print: json.dumps(...),应改为print()函数调用。 - 列表语法错误:
example_inventory方法中 hosts 数组的 IP 地址之间缺少逗号分隔,运行会触发语法错误。 - 方法缩进错误:
example_inventory方法定义没有缩进在ExampleInventory类内部,属于类外游离函数,类实例调用时找不到该方法。 - 功能适配:如果期望输出
web1/web2/db1/db2作为主机名而非 IP,只需将 hosts 列表改为对应主机名,在 hostvars 中添加ansible_host字段指定实际连接 IP 即可。
修正后完整代码
#!/usr/bin/env python3 ''' Custom dynamic inventory script for ansible, in python ''' import os import sys import argparse try: import json except ImportError: import simplejson as json class ExampleInventory(object): def __init__(self): self.inventory = {} self.read_cli_args() # 调用--list返回全量清单 if self.args.list: self.inventory = self.example_inventory() # 调用--host返回单主机变量 elif self.args.host: self.inventory = self.empty_inventory() else: self.inventory = self.empty_inventory() print(json.dumps(self.inventory)) # 测试用硬编码清单,实际使用可替换为云API查询逻辑 def example_inventory(self): # 若要使用web1等别名作为主机名,使用下方注释代码即可 # return { # "group": { # "hosts": [ # "web1", # "web2", # "db1", # "db2" # ], # "vars": { # "example_variable": "value" # } # }, # "_meta":{ # "hostvars": { # "web1": { # "ansible_host": "172.31.30.220", # "host_specific_vars": "web1" # }, # "web2": { # "ansible_host": "172.31.28.102", # "host_specific_vars": "web2" # }, # "db1": { # "ansible_host": "172.31.32.33", # "host_specific_vars": "db1" # }, # "db2": { # "ansible_host": "172.31.41.111", # "host_specific_vars": "db2" # } # } # } # } # 保留原IP作为主机名的实现 return { "group": { "hosts": [ "172.31.30.220", "172.31.28.102", "172.31.32.33", "172.31.41.111" ], "vars": { "example_variable": "value" } }, "_meta":{ "hostvars": { "172.31.30.220": { "host_specific_vars": "web1" }, "172.31.28.102": { "host_specific_vars": "web2" }, "172.31.32.33": { "host_specific_vars": "db1" }, "172.31.41.111": { "host_specific_vars": "db2" } } } } def empty_inventory(self): return {'_meta': {'hostvars': {}}} def read_cli_args(self): parser = argparse.ArgumentParser() parser.add_argument('--list', action = 'store_true') parser.add_argument('--host', action = 'store') self.args = parser.parse_args() if __name__ == "__main__": ExampleInventory()
验证方式
- 执行
python3 脚本文件名.py --list即可输出完整清单结构,包含所有主机及对应hostvars变量。 - 执行
python3 脚本文件名.py --host 主机名/IP可返回单台主机的变量信息。
内容的提问来源于stack exchange,提问作者Odira
相关产品推荐
相关产品推荐

