def my_add_group(self, hosts, groupname, groupvars=None): my_group = Group(name=groupname) if groupvars: for key, value in groupvars.iteritems(): my_group.set_variable(key, value) for host in hosts: hostname = host.get('hostname') hostip = host.get('ip', hostname) hostport = host.get('port', 22) username = host.get('username', 'root') password = host.get('password') ssh_key = host.get("ssh_key") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) for key, value in host.iteritems(): if key not in ['hostname', 'port', 'username', 'password']: my_host.set_variable(key, value) my_group.add_host(my_host) self.inventory.add_group(my_group)
def my_add_group(self, hosts, groupname, groupvars=None): ''' add hosts to a group ''' my_group = Group(name=groupname) # if group variables exists, add them to group if groupvars: for key, value in groupvars.items(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables hostname = host.get('hostname') hostip = host.get('ip', hostname) hostport = host.get('port') username = host.get('username') password = host.get('password') ssh_key = host.get('ssh_key') my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) # set other variables for key, value in host.items(): if key not in ['hostname', 'port', 'username', 'password']: my_host.set_variable(key, value) # add to group my_group.add_host(my_host) self.add_group(my_group)
def _parse(self, err): all_hosts = {} self.raw = utils.parse_json(self.data) 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. if group_name == '_meta': if 'hostvars' in data: self.host_vars_from_top = data['hostvars'] continue group = groups[group_name] = Group(group_name) host = None if not isinstance(data, dict): data = {'hosts': data} elif not any(k in data for k in ('hosts','vars')): data = {'hosts': [group_name], 'vars': data} if 'hosts' in 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) if 'vars' in data: for k, v in data['vars'].iteritems(): if group.name == all.name: all.set_variable(k, v) else: group.set_variable(k, v) if group.name != all.name: all.add_child_group(group) # 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]) return groups
def my_add_group(self, hosts, groupname, groupvars=None): """ add hosts to a group """ my_group = Group(name=groupname) # if group variables exists, add them to group if groupvars: for key, value in groupvars.iteritems(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables hostname = host.get("hostname") hostip = host.get('ip', hostname) hostport = host.get("port") username = host.get("username") password = host.get("password") ssh_key = host.get("ssh_key") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) # set other variables for key, value in host.iteritems(): if key not in ["hostname", "port", "username", "password"]: my_host.set_variable(key, value) # add to group my_group.add_host(my_host) self.inventory.add_group(my_group)
def add_dynamic_group(self, hosts, groupname, groupvars=None): """ add hosts to a group """ self.inventory.add_group(groupname) my_group = Group(name=groupname) # if group variables exists, add them to group if groupvars: for key, value in groupvars.items(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables hostname = host.get("hostname", None) hostip = host.get('ip', None) if hostip is None: print("IP地址为空,跳过该元素。") continue hostport = host.get("port", 22) user = host.get("user", 'root') password = host.get("password", None) ssh_key = host.get("ssh_key", None) if hostname is None: hostname = hostip my_host = Host(name=hostname, port=hostport) self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_port', value=hostport) self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_host', value=hostip) self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_user', value=user) if password: self.variable_manager.set_host_variable( host=my_host, varname='ansible_ssh_pass', value=password) if ssh_key: self.variable_manager.set_host_variable( host=my_host, varname='ansible_ssh_private_key_file', value=ssh_key) # set other variables for key, value in host.items(): if key not in ["hostname", "port", "user", "password"]: self.variable_manager.set_host_variable(host=my_host, varname=key, value=value) # add to group self.inventory.add_host(host=hostname, group=groupname, port=hostport)
def test_get_group_vars_with_nested_groups(self): parent_group = Group('some_parent_group') parent_group.set_variable('parent_some_key', 'parent_some_value') child_group = Group('some_child_group') child_group.set_variable('child_some_key', 'child_some_value') parent_group.add_child_group(child_group) self.hostA.add_group(child_group) group_vars = self.hostA.get_group_vars() self.assertIsInstance(group_vars, dict) self.assertIn('parent_some_key', group_vars) self.assertIn('child_some_key', group_vars)
def gen_group(group_name=None, group_vars={}): """ Generate ansible Group object :param group_name: <string> Group Name :param group_vars: <dict> Group Variables :return: ansible Group object """ group = Group(name=group_name) for key, value in group_vars.iteritems(): group.set_variable(key, value) return group
def add_zdy_group(self): # 添加自定义的组 if isinstance(self._group_name, str) and self._group_name: # 自定义组名 zdy_group = Group(self._group_name) self.add_group(zdy_group) # 为主机组添加额外参数 # 添加外部变量 if self._group_ext_vars and isinstance(self._group_ext_vars, dict): for k, v in self._group_ext_vars.items(): zdy_group.set_variable(k, v)
def _parse(self, err): all_hosts = {} self.raw = utils.parse_json(self.data) 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(): group = groups[group_name] = Group(group_name) host = None if not isinstance(data, dict): data = {'hosts': data} elif not any(k in data for k in ('hosts', 'vars')): data = {'hosts': [group_name], 'vars': data} if 'hosts' in 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) if 'vars' in data: for k, v in data['vars'].iteritems(): if group.name == all.name: all.set_variable(k, v) else: group.set_variable(k, v) if group.name != all.name: all.add_child_group(group) # Separate loop to ensure all groups are defined for (group_name, data) in self.raw.items(): 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]) return groups
def my_add_group(self, hosts, groupname, groupvars=None): """ add hosts to a group """ my_group = Group(name=groupname) # if group variables exists, add them to group if groupvars: for key, value in groupvars.iteritems(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables hostname = host.get("hostname") hostip = host.get('ip', hostname) hostport = host.get("port") # 临时增加的端口验证,如果22不通,则连接21987 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk.settimeout(1) try: sk.connect((hostip,22)) hostport = 22 except Exception: hostport = 21987 # END username = host.get("username") password = host.get("password") ssh_key = host.get("ssh_key") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) # set other variables for key, value in host.iteritems(): if key not in ["hostname", "port", "username", "password"]: my_host.set_variable(key, value) # add to group my_group.add_host(my_host) self.inventory.add_group(my_group)
def _parse(self, err): all_hosts = {} # not passing from_remote because data from CMDB is trusted self.raw = utils.parse_json(self.data) self.raw = json_dict_bytes_to_unicode(self.raw) 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. if group_name == '_meta': if 'hostvars' in data: self.host_vars_from_top = data['hostvars'] continue if group_name != all.name: group = groups[group_name] = Group(group_name) else: group = all host = None if not isinstance(data, dict): data = {'hosts': data} # is not those subkeys, then simplified syntax, host with vars elif not any(k in data for k in ('hosts','vars')): data = {'hosts': [group_name], 'vars': data} 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) 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]) for group in groups.values(): if group.depth == 0 and group.name != 'all': all.add_child_group(group) return groups
def _parse(self, data): all = Group('all') ungrouped = Group('ungrouped') all.add_child_group(ungrouped) self.groups = dict(all=all, ungrouped=ungrouped) grouped_hosts = [] yaml = utils.parse_yaml(data) # first add all groups for item in yaml: if type(item) == dict and 'group' in item: group = Group(item['group']) for subresult in item.get('hosts',[]): if type(subresult) in [ str, unicode ]: host = self._make_host(subresult) group.add_host(host) grouped_hosts.append(host) elif type(subresult) == dict: host = self._make_host(subresult['host']) vars = subresult.get('vars',{}) if type(vars) == list: for subitem in vars: for (k,v) in subitem.items(): host.set_variable(k,v) elif type(vars) == dict: for (k,v) in subresult.get('vars',{}).items(): host.set_variable(k,v) else: raise errors.AnsibleError("unexpected type for variable") group.add_host(host) grouped_hosts.append(host) vars = item.get('vars',{}) if type(vars) == dict: for (k,v) in item.get('vars',{}).items(): group.set_variable(k,v) elif type(vars) == list: for subitem in vars: if type(subitem) != dict: raise errors.AnsibleError("expected a dictionary") for (k,v) in subitem.items(): group.set_variable(k,v) self.groups[group.name] = group all.add_child_group(group) # add host definitions for item in yaml: if type(item) in [ str, unicode ]: host = self._make_host(item) if host not in grouped_hosts: ungrouped.add_host(host) elif type(item) == dict and 'host' in item: host = self._make_host(item['host']) vars = item.get('vars', {}) if type(vars)==list: varlist, vars = vars, {} for subitem in varlist: vars.update(subitem) for (k,v) in vars.items(): host.set_variable(k,v) if host not in grouped_hosts: ungrouped.add_host(host)
def parse_inventory(self, host_list): if isinstance(host_list, string_types): if "," in host_list: host_list = host_list.split(",") host_list = [h for h in host_list if h and h.strip()] self.parser = None # Always create the 'all' and 'ungrouped' groups, even if host_list is # empty: in this case we will subsequently an the implicit 'localhost' to it. ungrouped = Group('ungrouped') all = Group('all') all.add_child_group(ungrouped) # 加一个本地IP ''' local_group = Group('local') ''' # 自定义组名 zdy_group_name = Group(self.group_name) self.groups = { self.group_name: zdy_group_name, "all": all, "ungrouped": ungrouped } #self.groups = {self.group_name:zdy_group_name,"all":all,"ungrouped":ungrouped,"local":local_group} #self.groups = dict(all=all, ungrouped=ungrouped) if host_list is None: pass elif isinstance(host_list, list): # 默认添加一个本地IP ''' (lhost, lport) = parse_address('127.0.0.1', allow_ranges=False) new_host = Host(lhost, lport) local_group.add_host(new_host) ''' for h in host_list: try: (host, port) = parse_address(h, allow_ranges=False) except AnsibleError as e: display.vvv( "Unable to parse address from hostname, leaving unchanged: %s" % to_text(e)) host = h port = None new_host = Host(host, port) if h in C.LOCALHOST: # set default localhost from inventory to avoid creating an implicit one. Last localhost defined 'wins'. if self.localhost is not None: display.warning( "A duplicate localhost-like entry was found (%s). First found localhost was %s" % (h, self.localhost.name)) display.vvvv("Set default localhost to %s" % h) self.localhost = new_host # 为组添加host zdy_group_name.add_host(new_host) # 为主机组添加额外参数 # 添加外部变量 if self.ext_vars and isinstance(self.ext_vars, dict): for k, v in self.ext_vars.items(): zdy_group_name.set_variable(k, v) # local_group.set_variable(k,v) elif self._loader.path_exists(host_list): # TODO: switch this to a plugin loader and a 'condition' per plugin on which it should be tried, restoring 'inventory pllugins' if self.is_directory(host_list): # Ensure basedir is inside the directory host_list = os.path.join(self.host_list, "") self.parser = InventoryDirectory(loader=self._loader, groups=self.groups, filename=host_list) else: self.parser = get_file_parser(host_list, self.groups, self._loader) vars_loader.add_directory(self._basedir, with_subdir=True) if not self.parser: # should never happen, but JIC raise AnsibleError( "Unable to parse %s as an inventory source" % host_list) else: display.warning("Host file not found: %s" % to_text(host_list)) self._vars_plugins = [x for x in vars_loader.all(self)] # set group vars from group_vars/ files and vars plugins for g in self.groups: group = self.groups[g] group.vars = combine_vars(group.vars, self.get_group_variables(group.name)) self.get_group_vars(group) # get host vars from host_vars/ files and vars plugins for host in self.get_hosts(ignore_limits=True, ignore_restrictions=True): host.vars = combine_vars(host.vars, self.get_host_variables(host.name)) self.get_host_vars(host)
# -*-coding:utf-8 -*-
def _add_dynamic_group(self, hosts_list, groupname, groupvars=None): """ 动态添加主机到指定的主机组 完整的HOSTS文件格式 [test1] hostname ansible_ssh_host=192.168.1.111 ansible_ssh_user="******" ansible_ssh_pass="******" 但通常我们都省略hostname,端口也省略因为默认是22,这个在ansible配置文件中有,除非有非22端口的才会配置 [test1] 192.168.100.10 ansible_ssh_user="******" ansible_ssh_pass="******" ansible_python_interpreter="/PATH/python3/bin/python3" :param hosts_list: 主机列表 [{"ip": "192.168.100.10", "port": "22", "username": "******", "password": None}, {}] :param groupname: 组名称 :param groupvars: 组变量,格式为字典 :return: """ # 添加组 my_group = Group(name=groupname) self._inventory.add_group(groupname) # 添加组变量 if groupvars: for key, value in groupvars.items(): my_group.set_variable(key, value) # 添加一个主机 for host in hosts_list: hostname = host.get("hostname", None) hostip = host.get("ip", None) if hostip is None: print("IP地址为空,跳过该元素。") continue hostport = host.get("port", "22") username = host.get("username", "root") password = host.get("password", None) ssh_key = host.get("ssh_key", None) python_interpreter = host.get("python_interpreter", None) try: # hostname可以不写,如果为空默认就是IP地址 if hostname is None: hostname = hostip # 添加主机到组 self._inventory.add_host(host=hostname, group=groupname, port=hostport) inv_host = self._inventory.get_host(hostname) # 添加主机变量 inv_host.set_variable('ansible_ssh_host', hostip) inv_host.set_variable('ansible_ssh_port', hostport) inv_host.set_variable('ansible_ssh_user', username) if password: inv_host.set_variable('ansible_ssh_pass', password) if ssh_key: inv_host.set_variable('ansible_ssh_private_key_file', ssh_key) if python_interpreter: inv_host.set_variable('ansible_python_interpreter', python_interpreter) # 添加其他变量 for key, value in host.items(): if key not in [ "ip", "hostname", "port", "username", "password", "ssh_key", "python_interpreter" ]: inv_host.set_variable(key, value) except Exception as err: print(err)
def _parse(self, err): all_hosts = {} # not passing from_remote because data from CMDB is trusted self.raw = utils.parse_json(self.data) # 还是使用self.data来解析标准输出,需要self.data为json格式数据 self.raw = json_dict_bytes_to_unicode(self.raw) # 将self.raw中的kv都转换成unicode格式。 all = Group('all') # 设置Group("all") groups = dict(all=all) # 初始化groups字典 group = None if 'failed' in self.raw: # 如果self.raw中有failed字段,则报错。不过在上面parser_json的时候no_exception是false,不会出现failed情况 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(): # 1.3 以上版本使用--list的时返回结果中会包含_meta这样的key,该key的value中会有一个hostvars变量,该变量包含每个host的主机变量 # 1.2及以下版本仍然需要使用--host命令为每一个host返回主机变量 # 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. """ { "databases" : { "hosts" : [ "host1.example.com", "host2.example.com" ], "vars" : { "a" : true } }, "webservers" : [ "host2.example.com", "host3.example.com" ], "atlanta" : { "hosts" : [ "host1.example.com", "host4.example.com", "host5.example.com" ], "vars" : { "b" : false }, "children": [ "marietta", "5points" ] }, "marietta" : [ "host6.example.com" ], "5points" : [ "host7.example.com" ] } { # results of inventory script as above go here # ... "_meta" : { "hostvars" : { "moocow.example.com" : { "asdf" : 1234 }, "llama.example.com" : { "asdf" : 5678 }, } } { "moocow.example.com" : { "asdf" : 1234 }, "llama.example.com" : { "asdf" : 5678 } } """ if group_name == '_meta': # 如果key为_meta,则该value为meta数据。 if 'hostvars' in data: self.host_vars_from_top = data['hostvars'] # 如果meta数据中包含hostvars,则缓存到self.host_vars_from_top中。 continue # 跳过之后的处理 if group_name != all.name: # group_name不是all则创建新的Group对象,并加入groups字典。 group = groups[group_name] = Group(group_name) # 如果data中出现无group的hostname,则会出现以hostname为名称的组 else: group = all host = None if not isinstance(data, dict): # 如果data不是字典类型,则表示data为主机列表 data = {'hosts': data} # is not those subkeys, then simplified syntax, host with vars elif not any(k in data for k in ('hosts','vars','children')): # any函数表示可迭代对象中任何一个为True,则为True.否则为False # 如果data对象是字典类型,但key中不存在hosts、vars、children时,既该行数据为主机变量数据时,group_name为主机名 data = {'hosts': [group_name], 'vars': data} # 上面两步为了统一data的格式,不带变量的data,格式为{'hosts': [host1,host2...] # 带变量的data,格式为: {'hosts': [group_name], 'vars': data } if 'hosts' in data: if not isinstance(data['hosts'], list): # 主机列表必须是list对象,上面的'hosts': [group_name] 也是为校验统一格式 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) # 如果主机对象不存在, 则创建并添加到all_hosts列表中,去重 host = all_hosts[hostname] # 将Host对象赋值给host变量 group.add_host(host) # 将Host对象添加到该group中 if 'vars' in data: # 如果是带有vars的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",则将变量加到all group中,否则加到当前group中。 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: # 如果data中包含子组,遍历子组并将子组添加到父组中 for child_name in data['children']: if child_name in groups: groups[group_name].add_child_group(groups[child_name]) for group in groups.values(): if group.depth == 0 and group.name != 'all': # 如果该组深度为0,且名称不是"all",则加入all组的子组列表中。 all.add_child_group(group) return groups