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

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

动态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 

转载地址:http://viwdo.baihongyu.com/

你可能感兴趣的文章
(2编写网络)自己动手,编写神经网络程序,解决Mnist问题,并网络化部署
查看>>
【转】如何使用分区助手完美迁移系统到SSD固态硬盘?
查看>>
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
查看>>
就是要你懂TCP -- 握手和挥手
查看>>
Andrew Ng机器学习公开课笔记 -- Regularization and Model Selection
查看>>
《Python游戏编程快速上手》一1.3 如何使用本书
查看>>
《Visual Studio程序员箴言》----1.2 滚动与导航
查看>>
Processing编程学习指南2.7 Processing参考文档
查看>>
架构师速成-架构目标之伸缩性\安全性
查看>>
执行可运行jar包时读取jar包中的文件
查看>>
linux下ExtMail邮件使用及管理平台
查看>>
linux中iptables设置自建dns服务器的端口
查看>>
基于Yum安装zabbix3.0
查看>>
Master-work模式
查看>>
RT-Thread--时间管理
查看>>
BUPT 63T 高才生 找最佳基站
查看>>
linux 学习(二)防火墙
查看>>
scala001
查看>>
android - SpannableString或SpannableStringBuilder以及string.xml文件中的整型和string型代替...
查看>>
自己选择的路,跪着走完吧——一个兔纸的话
查看>>