博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ansible源码解析Inventory动态inventory脚本解析script.py
阅读量:7232 次
发布时间:2019-06-29

本文共 4852 字,大约阅读时间需要 16 分钟。

动态inventory script.py

说明

也是一个比较简单的模块,解析脚本、解析json、通过基本类封装group host完事。

必须支持--list方法,而且是可执行文件。

class InventoryScript(object):    ''' Host inventory parser for ansible using external inventory scripts. '''    def __init__(self, filename=C.DEFAULT_HOST_LIST):        # Support inventory scripts that are not prefixed with some        # path information but happen to be in the current working        # directory when '.' is not in PATH.        # 获取绝对路径        self.filename = os.path.abspath(filename)        # 参数        cmd = [ self.filename, "--list" ]        try:            # 尝试调用调用出错或是返回码不为0的话就直接报错            sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)        except OSError, e:            raise errors.AnsibleError("problem running %s (%s)" % (' '.join(cmd), e))        (stdout, stderr) = sp.communicate()        if sp.returncode != 0:            raise errors.AnsibleError("Inventory script (%s) had an execution error: %s " % (filename,stderr))        self.data = stdout        # see comment about _meta below        self.host_vars_from_top = None        self.groups = self._parse(stderr)    # 这个方法是核心    def _parse(self, err):        all_hosts = {}        # not passing from_remote because data from CMDB is trusted        # 通过json解析, json_dict_bytes_to_unicode        self.raw  = utils.parse_json(self.data)        # 递归解析字典、列表、元组去一个字符串,这是一个内置的方法        self.raw  = json_dict_bytes_to_unicode(self.raw)        # 和group类处理的相同        all       = Group('all')        groups    = dict(all=all)        group     = None        # 有错误输出        if 'failed' in self.raw:            sys.stderr.write(err + "\n")            raise errors.AnsibleError("failed to parse executable inventory script results: %s" % self.raw)        # 获取组信息        for (group_name, data) in self.raw.items():            # in Ansible 1.3 and later, a "_meta" subelement may contain            # a variable "hostvars" which contains a hash for each host            # if this "hostvars" exists at all then do not call --host for each            # host.  This is for efficiency and scripts should still return data            # if called with --host for backwards compat with 1.2 and earlier.            # 这个_meta一般为主机设置环境变量,即可以不通过--host再去获取主机的相应信息            # 这个方法主要是为了省带宽            if group_name == '_meta':                if 'hostvars' in data:                    # 设置这完意,然后就进行下一次循环                    self.host_vars_from_top = data['hostvars']                    continue            # 组名不是all 就实例一个group            if group_name != all.name:                group = groups[group_name] = Group(group_name)            else:                group = all            host = None            # data不是字典直接赋值            if not isinstance(data, dict):                data = {
'hosts': data} # is not those subkeys, then simplified syntax, host with vars # 看过group的很好理解 elif not any(k in data for k in ('hosts','vars','children')): data = {
'hosts': [group_name], 'vars': data} # hosts在组里面,并且不是列表就报错,不然就添加主机进这个组 if 'hosts' in data: if not isinstance(data['hosts'], list): raise errors.AnsibleError("You defined a group \"%s\" with bad " "data for the host list:\n %s" % (group_name, data)) # 添加主机进这个组 for hostname in data['hosts']: if not hostname in all_hosts: all_hosts[hostname] = Host(hostname) host = all_hosts[hostname] group.add_host(host) # 设置组的环境变量,同样做个异常判断不是字段就报错 # 同上因为主机是列表,而变量是key/value形式 if 'vars' in data: if not isinstance(data['vars'], dict): raise errors.AnsibleError("You defined a group \"%s\" with bad " "data for variables:\n %s" % (group_name, data)) for k, v in data['vars'].iteritems(): if group.name == all.name: all.set_variable(k, v) else: group.set_variable(k, v) # Separate loop to ensure all groups are defined # 添加子组 for (group_name, data) in self.raw.items(): if group_name == '_meta': continue if isinstance(data, dict) and 'children' in data: for child_name in data['children']: if child_name in groups: groups[group_name].add_child_group(groups[child_name]) # 这里搞定all组 for group in groups.values(): if group.depth == 0 and group.name != 'all': all.add_child_group(group) return groups # 这里就是--host的处理了 def get_host_variables(self, host): """ Runs
本文转自 煮酒品茶 51CTO博客,原文链接:http://blog.51cto.com/cwtea/2044739,如需转载请自行联系原作者
你可能感兴趣的文章
OWIN and Katana
查看>>
(原創) 如何確保傳進function的array不被任意更改? (C/C++) (C)
查看>>
(原創) 如何讓Quartus II 8.0的Programmer不要另開新視窗? (SOC) (Quartus II)
查看>>
asp.net下使用CKEditor和CKFinder
查看>>
STM32 ADC学习
查看>>
你所不知道的传输层
查看>>
EMACS::基本操作
查看>>
matlab练习程序(最小二乘多项式拟合)
查看>>
POJ 1149 PIGS (Dinic 或 EK)
查看>>
Vista SP1 vs. XP SP2 - Benchmarked
查看>>
深入理解CSS中的行高
查看>>
算法阶段4
查看>>
压缩感知简介
查看>>
postgresql之checkpoints
查看>>
MFC对话框打印预览异常问题解决
查看>>
文件系统管理 之 文件和目录访问权限设置
查看>>
Core Java-多线程-线程的生命周期
查看>>
打动人的自我介绍
查看>>
python:Attempted relative import in non-package
查看>>
CRF++中文分词使用指南
查看>>