コード例 #1
0
ファイル: ansible_api.py プロジェクト: hatmen/pystudy
    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)
コード例 #2
0
    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)
コード例 #3
0
ファイル: script.py プロジェクト: zoni/ansible
    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
コード例 #4
0
ファイル: ansible_api.py プロジェクト: jinrenlab/MagicStack
    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)
コード例 #5
0
    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)
コード例 #6
0
    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)
コード例 #7
0
ファイル: test_host.py プロジェクト: Rajeshkumar90/Ansible
 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)
コード例 #8
0
ファイル: ansible_api.py プロジェクト: tom2jack/ansible_api
 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
コード例 #9
0
    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)
コード例 #10
0
    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
コード例 #11
0
    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)
コード例 #12
0
    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
コード例 #13
0
ファイル: yaml.py プロジェクト: ucxdvd/n-repo
    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)
コード例 #14
0
    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)
コード例 #15
0
# -*-coding:utf-8 -*-
コード例 #16
0
ファイル: myAnsible.py プロジェクト: fengjp/cmdb
    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)
コード例 #17
0
ファイル: script.py プロジェクト: bopopescu/ansible-1
    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