Ansible源码解析 Inventory组概念
group.py
作者 煮酒品茶
一个组的Class,包含对外方法以及属性如下。
组做为inventory的子节点,会有嵌套组,组变量,组内主机,子组,父组的一些概念
[ 'name', 'hosts', 'vars', 'child_groups', 'parent_groups', 'depth', '_hosts_cache' ]
- name 主机名称,就是IP
- hosts 组内主机列表
- vars 组的变量
- child_groups 子组
- parent_groups 父组
- depth 深度,表示这个组有多少嵌套的组
- _hosts_cache 一个用来清理内存的方法
属性说明
虽然类是一个对象,但是我们有时可以把类看成一个字典,加一个方法
Group看起来就像一个字典,既然理解是一个字典,我们把结构分析出来。
记住这个结构就很好理解这个类,另外提供的方法都是为了实现这个实例
group_name = {"depth" : depth,"name" : name,"hosts" : [host, host, host], # 这里的host为host类的实例,看host类分析"vars" : {"key1" : "value1","key2" : "value2",},"child_groups" : [group, # 这里的group就是我们自己,一种深度的方式group, group,],"parent_group" : [group, # 这里的group就是我们自己group, group ,],# 这里的host为所有的子组子组的host的集合,# 代表这个组包含的所有主机"_hosts_cache" : [host, host, host]
}
方法说明
- add_child_group # 添加子组
- add_host # 添加主机,即添加到hosts属性当中
- set_variable # 设置环境变量,即vars当中
- clear_hosts_cache # 清空组内所有主机的缓存,这是一个属性
- get_hosts # 获取所有主机,当_hosts_cache不存在时,否则直接返回_hosts_cache
- get_variables # 获取所有变量
- get_ancestors # 获取所有父组
类原型
class Group(object):''' a group of ansible hosts '''__slots__ = [ 'name', 'hosts', 'vars', 'child_groups', 'parent_groups', 'depth', '_hosts_cache' ]def __init__(self, name=None):# 组内的主机、子组和父组是一个列表、变量为为字典self.depth = 0self.name = nameself.hosts = []self.vars = {}self.child_groups = []self.parent_groups = []self._hosts_cache = None#self.clear_hosts_cache()# 不允许没有不传组名,这里没有用真假, 个人认为用# if not self.name 为更好if self.name is None: raise Exception("group name is required")# 添加子组方法def add_child_group(self, group):if self == group: # 不允许自己添加自己raise Exception("can't add group to itself")# don't add if it's already there# 组名如果已经存在子组里面即不添加,这里的验证方式以组名认证# 同样认为用 if group not in self.child_groups会更好理解一点if not group in self.child_groups:# 添加子组,可以看到子组也是一个列表self.child_groups.append(group)# update the depth of the child# 更新组的深度,这里需要注意的是子组也是同样走这个类,而depth# 会动态生成, 比较当前组的深度 +1 与要添加的组的深度,哪个# 更大当前组的深度就为这个group.depth = max([self.depth+1, group.depth])# update the depth of the grandchildren# 更新子组的子组的深度,这里用的是注释是孙组# 但看函数原型则所有后辈组的深度为一样group._check_children_depth()# now add self to child's parent_groups list, but only if there# isn't already a group with the same name# 如果组名不在 父组列组的名称当中,用到了列表解析# 通过列表解析获取所有父组的名字来进行比对,不在即不同名,就添加# 到父组里面if not self.name in [g.name for g in group.parent_groups]:group.parent_groups.append(self)# 添缓存, 即子组与所有子组的 _hosts_cache为量为空self.clear_hosts_cache()# 验证子组深度,这是一个递归函数,这里可以知道的一点是# 所有后輩组的深度都是一样def _check_children_depth(self):# 递归所有子组for group in self.child_groups: # 子组的深度更新,保持与当前组一置group.depth = max([self.depth+1, group.depth])# 递归,所以所有子组的所有深度都会被改变group._check_children_depth()# 添加主机def add_host(self, host):# 往组的主机列表里添加这台主机self.hosts.append(host)# 同样把主机的组里面添加自己的组host.add_group(self)# 再清缓存, 即子组与所有子组的 _hosts_cache为量为空self.clear_hosts_cache()# 设置变量,这里对应的是组,所以设置的是组的变量def set_variable(self, key, value):self.vars[key] = value# 清空缓存def clear_hosts_cache(self):# 子组与所有子组的 _hosts_cache为量为空self._hosts_cache = Nonefor g in self.parent_groups:g.clear_hosts_cache()# 获取组内的主机def get_hosts(self):# 如果主机缓存在的话直接返回,否则返回内置方法# self._get_hosts()if self._hosts_cache is None:self._hosts_cache = self._get_hosts()return self._hosts_cache# 内置获取主机的方法, 用到集合的概念,但没有用集合的方法def _get_hosts(self):# hosts列表 seen 字典hosts = []seen = {}# 先遍历子组for kid in self.child_groups:# 一个递归,外部递归,获取子组的所有主机,即# 不管组多深,都能拿出子组所有的主机kid_hosts = kid.get_hosts()# 下面是做主机重复的判断,如果重复了就不加了for kk in kid_hosts:if kk not in seen:# 这里暂时没有意义,代表主机已经存在了seen[kk] = 1 # 不存在就添加主机hosts.append(kk)# 再遍历自己组的主机for mine in self.hosts:# 上面的seen作用主要体现在这儿,因为两个for# 命令空间不同所以写在这里做判断,同样存在即不添加# 保持hosts为一个组内的集合 集合是不会有同样的组的if mine not in seen:seen[mine] = 1hosts.append(mine)return hosts# 获取变量def get_variables(self):# 一份浅拷贝的变量,需要注意的是变量是没有潜逃的return self.vars.copy()# 获取所有父组的递归函数def _get_ancestors(self):results = {}for g in self.parent_groups:results[g.name] = gresults.update(g._get_ancestors())return resultsdef get_ancestors(self):return self._get_ancestors().values()
转载于:https://blog.51cto.com/cwtea/2043640
Ansible源码解析 Inventory组概念相关推荐
- spark源码解析之基本概念
从两方面来阐述spark的组件,一个是宏观上,一个是微观上. 1. spark组件 要分析spark的源码,首先要了解spark是如何工作的.spark的组件: 了解其工作过程先要了解基本概念 官方罗 ...
- 《OV4689摄像头模组驱动源码解析》
<OV4689摄像头模组驱动源码解析> OV4689是一款广泛应用于工业.安防等领域的高清图像传感器.在这篇文章中,我们将介绍如何在单片机上使用OV4689模组,并提供相应的驱动源码. O ...
- Colly源码解析——结合例子分析底层实现
通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...
- Laravel源码解析之从入口开始
前言 提升能力的方法并非使用更多工具,而是解刨自己所使用的工具.今天我们从Laravel启动的第一步开始讲起. 入口文件 laravel是单入口框架,所有请求必将经过index.php define( ...
- 面试官系统精讲Java源码及大厂真题 - 27 Thread 源码解析
27 Thread 源码解析 书籍乃世人积累智慧之长明灯. 引导语 从本章开始我们开始学习线程的知识,线程是非常有趣的一个章节,大多数同学对于线程 API,属于不用就忘,到用时需要百度的情况,希望通过 ...
- 详细讲解go web框架之gin框架源码解析记录及思路流程和理解
开篇 首先gin 框架是在 官方提供的net/http标准包进行的相应封装. 那么要想理解gin框架, 就要先懂一些 net/http标准包 的相关知识. 可以参考中文的 文档: https://st ...
- 【移动开发】Checkout开源库源码解析
Checkout开源库的源码解析 1.功能介绍 1.1Checkout是什么 Checkout是Android In-App Billing API(v3 +)的一个封装库.In-App Billin ...
- [源码解析] PyTorch 分布式(2) ----- DataParallel(上)
[源码解析] PyTorch 分布式(2) ----- DataParallel(上) 文章目录 [源码解析] PyTorch 分布式(2) ----- DataParallel(上) 0x00 摘要 ...
- MySQL核心参数含义的源码解析
引言 你访问的网站,大部分使用Apache服务器;你访问的网站,大部分使用Linux或BSD操作系统:你访问的网站,大部分使用MySQL数据库;你提交DNS域名查询请求大多由BIND服务器分析处理;你 ...
最新文章
- 分科目统计每科前三名的学生
- 单例设计模式八种方式——5) 懒汉式(线程安全,同步代码块) 6) 双重检查 7) 静态内部类 8) 枚举
- pyaudio:基于pyaudio利用Python编程从电脑端录制音频保存到指定文件夹+将录音上传服务器+录音进行识别并转为文本保存
- django手机访问_Django从入门到大作业:2-见网页
- LeetCode 77.组合求和
- 【APICloud系列|12】ios真机调试时如何添加新设备的udid?
- 努比亚z17s刷原生安卓_电脑运行手机APP,不会没关系,我推荐你使用显卡服务器运行安卓模拟器...
- arduino 步进电机驱动库_Arduino基础入门篇27—步进电机驱动库的使用
- 汇编实例2——循环累加
- 详解MATLAB之freqz()函数
- dos下的for命令详解(zz)
- 看呐!一群方言在舌尖跳舞
- 月圆之夜,愿永无bug
- 推荐系统实战 --- 基于音乐播放推荐
- 贝叶斯算法应用于反垃圾邮件
- 17.文件操作(1)----初识文件操作
- 斯坦福AI Lab主任Chris Manning:我的第一次CVPR
- linux镜像烧录工具,树莓派操作系统镜像烧录方法指南
- 全球茶叶产量、消费量及进出口贸易分析:中国茶叶产量全球排名第一[图]
- 每日三个笑话-20151013
热门文章
- Jmeter脚本 GUI和非GUI启动方式
- swift轮播图代码
- 2010.10.30 OA 项目组一周工作报告
- [MFC]多线程传参问题 [AfxBeginThread]
- iOS下JS与OC互相调用(五)--UIWebView + WebViewJavascriptBridge
- UITextField长度限制的写法
- 决策树算法原理(ID3,C4.5)
- Koa2和Redux中间件源码研究
- firefly 编译opencv3.3.1, CMake报错
- Django restful-framework初步学习