コード例 #1
0
    def _add_host(self, host_info, iterator):
        '''
        Helper function to add a new host to inventory based on a task result.
        '''

        host_name = host_info.get('host_name')

        # Check if host in cache, add if not
        if host_name in self._inventory._hosts_cache:
            new_host = self._inventory._hosts_cache[host_name]
        else:
            new_host = Host(name=host_name)
            self._inventory._hosts_cache[host_name] = new_host

            allgroup = self._inventory.get_group('all')
            allgroup.add_host(new_host)

        # Set/update the vars for this host
        new_vars = host_info.get('host_vars', dict())
        new_host.vars = self._inventory.get_host_vars(new_host)
        new_host.vars.update(new_vars)

        new_groups = host_info.get('groups', [])
        for group_name in new_groups:
            if not self._inventory.get_group(group_name):
                new_group = Group(group_name)
                self._inventory.add_group(new_group)
                new_group.vars = self._inventory.get_group_variables(
                    group_name)
            else:
                new_group = self._inventory.get_group(group_name)

            new_group.add_host(new_host)

            # add this host to the group cache
            if self._inventory.groups is not None:
                if group_name in self._inventory.groups:
                    if new_host not in self._inventory.get_group(
                            group_name).hosts:
                        self._inventory.get_group(group_name).hosts.append(
                            new_host.name)

        # clear pattern caching completely since it's unpredictable what
        # patterns may have referenced the group
        self._inventory.clear_pattern_cache()

        # also clear the hostvar cache entry for the given play, so that
        # the new hosts are available if hostvars are referenced
        self._variable_manager.invalidate_hostvars_cache(play=iterator._play)
コード例 #2
0
ファイル: data.py プロジェクト: zengjie/ansible
    def add_group(self, group):
        ''' adds a group to inventory if not there already '''

        if group:
            if not isinstance(group, string_types):
                raise AnsibleError("Invalid group name supplied, expected a string but got %s for %s" % (type(group), group))
            if group not in self.groups:
                g = Group(group)
                self.groups[group] = g
                self._groups_dict_cache = {}
                display.debug("Added group %s to inventory" % group)
            else:
                display.debug("group %s already in inventory" % group)
        else:
            raise AnsibleError("Invalid empty/false group name provided: %s" % group)
コード例 #3
0
    def _add_host(self, host_info):
        '''
        Helper function to add a new host to inventory based on a task result.
        '''

        host_name = host_info.get('host_name')

        # Check if host in cache, add if not
        if host_name in self._inventory._hosts_cache:
            new_host = self._inventory._hosts_cache[host_name]
        else:
            new_host = Host(name=host_name)
            self._inventory._hosts_cache[host_name] = new_host

            allgroup = self._inventory.get_group('all')
            allgroup.add_host(new_host)

        # Set/update the vars for this host
        # FIXME: probably should have a set vars method for the host?
        new_vars = host_info.get('host_vars', dict())
        new_host.vars = self._inventory.get_host_vars(new_host)
        new_host.vars.update(new_vars)

        new_groups = host_info.get('groups', [])
        for group_name in new_groups:
            if not self._inventory.get_group(group_name):
                new_group = Group(group_name)
                self._inventory.add_group(new_group)
                new_group.vars = self._inventory.get_group_variables(
                    group_name)
            else:
                new_group = self._inventory.get_group(group_name)

            new_group.add_host(new_host)

            # add this host to the group cache
            if self._inventory.groups is not None:
                if group_name in self._inventory.groups:
                    if new_host not in self._inventory.get_group(
                            group_name).hosts:
                        self._inventory.get_group(group_name).hosts.append(
                            new_host.name)

        # clear pattern caching completely since it's unpredictable what
        # patterns may have referenced the group
        # FIXME: is this still required?
        self._inventory.clear_pattern_cache()
コード例 #4
0
ファイル: dir.py プロジェクト: zsolt-erl/ansible
    def __init__(self, filename=C.DEFAULT_HOST_LIST):
        self.names = os.listdir(filename)
        self.names.sort()
        self.directory = filename
        self.parsers = []
        self.hosts = {}
        self.groups = {}

        for i in self.names:

            if i.endswith("~") or i.endswith(".orig") or i.endswith(".bak"):
                continue
            if i.endswith(".ini"):
                # configuration file for an inventory script
                continue
            if i.endswith(".retry"):
                # this file is generated on a failed playbook and should only be
                # used when run specifically
                continue
            # These are things inside of an inventory basedir
            if i in ("host_vars", "group_vars", "vars_plugins"):
                continue
            fullpath = os.path.join(self.directory, i)
            if os.path.isdir(fullpath):
                parser = InventoryDirectory(filename=fullpath)
            elif utils.is_executable(fullpath):
                parser = InventoryScript(filename=fullpath)
            else:
                parser = InventoryParser(filename=fullpath)
            self.parsers.append(parser)
            # This takes a lot of code because we can't directly use any of the objects, as they have to blend
            for name, group in parser.groups.iteritems():
                if name not in self.groups:
                    self.groups[name] = Group(name)
                for k, v in group.get_variables().iteritems():
                    self.groups[name].set_variable(k, v)
                for host in group.get_hosts():
                    if host.name not in self.hosts:
                        self.hosts[host.name] = Host(host.name)
                    for k, v in host.vars.iteritems():
                        self.hosts[host.name].set_variable(k, v)
                    self.groups[name].add_host(self.hosts[host.name])
            # This needs to be a second loop to ensure all the parent groups exist
            for name, group in parser.groups.iteritems():
                for ancestor in group.get_ancestors():
                    self.groups[ancestor.name].add_child_group(
                        self.groups[name])
コード例 #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")

            # 临时增加的端口验证,如果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)
コード例 #6
0
ファイル: __init__.py プロジェクト: tgerla/ansible
    def parse_inventory(self, host_list):

        if isinstance(host_list, basestring):
            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

        if host_list is None:
            pass
        elif isinstance(host_list, list):
            all = Group('all')
            self.groups = [ all ]
            for h in host_list:
                (host, port) = parse_address(h, allow_ranges=False)
                all.add_host(Host(host, port))
        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._loader.is_directory(host_list):
                # Ensure basedir is inside the directory
                host_list = os.path.join(self.host_list, "")
                self.parser = InventoryDirectory(loader=self._loader, filename=host_list)
            else:
                self.parser = get_file_parser(host_list, self._loader)
                vars_loader.add_directory(self.basedir(), with_subdir=True)

            if self.parser:
                self.groups = self.parser.groups.values()
            else:
                # should never happen, but JIC
                raise AnsibleError("Unable to parse %s as an inventory source" % host_list)

        self._vars_plugins = [ x for x in vars_loader.all(self) ]

        # FIXME: shouldn't be required, since the group/host vars file
        #        management will be done in VariableManager
        # get group vars from group_vars/ files and vars plugins
        for group in self.groups:
            group.vars = combine_vars(group.vars, self.get_group_variables(group.name))

        # get host vars from host_vars/ files and vars plugins
        for host in self.get_hosts():
            host.vars = combine_vars(host.vars, self.get_host_variables(host.name))
コード例 #7
0
    def _parse(self, data):
        '''
        Populates self.groups from the given array of lines. Raises an error on
        any parse failure.
        '''

        self._compile_patterns()

        # We expect top level keys to correspond to groups, iterate over them
        # to get host, vars and subgroups (which we iterate over recursivelly)
        for group_name in data.keys():
            self._parse_groups(group_name, data[group_name])

        # Finally, add all top-level groups as children of 'all'.
        # We exclude ungrouped here because it was already added as a child of
        # 'all' at the time it was created.
        for group in self.groups.values():
            if group.depth == 0 and group.name not in ('all', 'ungrouped'):
                self.groups['all'].add_child_group(Group(group_name))
コード例 #8
0
    def _add_group(self, task, iterator):
        '''
        Helper function to add a group (if it does not exist), and to assign the
        specified host to that group.
        '''

        # the host here is from the executor side, which means it was a
        # serialized/cloned copy and we'll need to look up the proper
        # host object from the master inventory
        groups = {}
        changed = False

        for host in self._inventory.get_hosts():
            original_task = iterator.get_original_task(host, task)
            all_vars = self._variable_manager.get_vars(loader=self._loader,
                                                       play=iterator._play,
                                                       host=host,
                                                       task=original_task)
            templar = Templar(loader=self._loader, variables=all_vars)
            group_name = templar.template(original_task.args.get('key'))
            if task.evaluate_conditional(templar=templar, all_vars=all_vars):
                if group_name not in groups:
                    groups[group_name] = []
                groups[group_name].append(host)

        for group_name, hosts in iteritems(groups):
            new_group = self._inventory.get_group(group_name)
            if not new_group:
                # create the new group and add it to inventory
                new_group = Group(name=group_name)
                self._inventory.add_group(new_group)
                new_group.vars = self._inventory.get_group_vars(new_group)

                # and add the group to the proper hierarchy
                allgroup = self._inventory.get_group('all')
                allgroup.add_child_group(new_group)
                changed = True
            for host in hosts:
                if group_name not in host.get_groups():
                    new_group.add_host(host)
                    changed = True

        return changed
コード例 #9
0
    def test_ancestor_example(self):
        # see docstring for Group._walk_relationship
        groups = {}
        for name in ['A', 'B', 'C', 'D', 'E', 'F']:
            groups[name] = Group(name)
        # first row
        groups['A'].add_child_group(groups['D'])
        groups['B'].add_child_group(groups['D'])
        groups['B'].add_child_group(groups['E'])
        groups['C'].add_child_group(groups['D'])
        # second row
        groups['D'].add_child_group(groups['E'])
        groups['D'].add_child_group(groups['F'])
        groups['E'].add_child_group(groups['F'])

        self.assertEqual(
            set(groups['F'].get_ancestors()),
            set([
                groups['A'], groups['B'], groups['C'], groups['D'], groups['E']
            ]))
コード例 #10
0
    def __init__(self, host_list=C.DEFAULT_HOST_LIST):

        # the host file file, or script path, or list of hosts
        # if a list, inventory data will NOT be loaded
        self.host_list = host_list

        # the inventory object holds a list of groups
        self.groups = []

        # a list of host(names) to contain current inquiries to
        self._restriction = None

        # whether the inventory file is a script
        self._is_script = False

        if type(host_list) in [str, unicode]:
            if host_list.find(",") != -1:
                host_list = host_list.split(",")

        if type(host_list) == list:
            all = Group('all')
            self.groups = [all]
            for x in host_list:
                if x.find(":") != -1:
                    tokens = x.split(":", 1)
                    all.add_host(Host(tokens[0], tokens[1]))
                else:
                    all.add_host(Host(x))
        elif os.access(host_list, os.X_OK):
            self._is_script = True
            self.parser = InventoryScript(filename=host_list)
            self.groups = self.parser.groups.values()
        else:
            data = file(host_list).read()
            if not data.startswith("---"):
                self.parser = InventoryParser(filename=host_list)
                self.groups = self.parser.groups.values()
            else:
                self.parser = InventoryParserYaml(filename=host_list)
                self.groups = self.parser.groups.values()
コード例 #11
0
ファイル: ini.py プロジェクト: zakkak/ansible
    def _parse_group_children(self):
        group = None

        for line in self.lines:
            line = line.strip()
            if line is None or line == '':
                continue
            if line.startswith("[") and ":children]" in line:
                line = line.replace("[","").replace(":children]","")
                group = self.groups.get(line, None)
                if group is None:
                    group = self.groups[line] = Group(name=line)
            elif line.startswith("#") or line.startswith(";"):
                pass
            elif line.startswith("["):
                group = None
            elif group:
                kid_group = self.groups.get(line, None)
                if kid_group is None:
                    raise AnsibleError("child group is not defined: (%s)" % line)
                else:
                    group.add_child_group(kid_group)
コード例 #12
0
    def _parse_group_children(self):
        # 在完成子组的添加后,需要对子组进行解析
        group = None

        for lineno in range(len(self.lines)):
            line = self.lines[lineno].strip()
            if line is None or line == '':
                continue
            if line.startswith("[") and ":children]" in line: # 表示改行是子组段
                line = line.replace("[","").replace(":children]","")
                group = self.groups.get(line, None) # 如果group并不存在于self.groups中,则创建新的Group对象,并添加
                if group is None:
                    group = self.groups[line] = Group(name=line)
            elif line.startswith("#") or line.startswith(";"): # 跳过注释
                pass
            elif line.startswith("["): # 其他以中括号开头的行都跳过,并重新初始化group
                group = None
            elif group: # 只有在[xxx:children] 格式后面的行的group才不为None
                kid_group = self.groups.get(line, None)
                if kid_group is None: # 子组必须是已经在之前的步骤中添加到self.groups中
                    raise errors.AnsibleError("%s:%d: child group is not defined: (%s)" % (self.filename, lineno + 1, line))
                else:
                    group.add_child_group(kid_group) # 将该子组加到当前组的子组集合中
コード例 #13
0
    def _add_group(self, host, group_name):
        '''
        Helper function to add a group (if it does not exist), and to assign the
        specified host to that group.
        '''

        new_group = self._inventory.get_group(group_name)
        if not new_group:
            # create the new group and add it to inventory
            new_group = Group(group_name)
            self._inventory.add_group(new_group)

            # and add the group to the proper hierarchy
            allgroup = self._inventory.get_group('all')
            allgroup.add_child_group(new_group)

        # the host here is from the executor side, which means it was a
        # serialized/cloned copy and we'll need to look up the proper
        # host object from the master inventory
        actual_host = self._inventory.get_host(host.name)

        # and add the host to the group
        new_group.add_host(actual_host)
コード例 #14
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)
            my_host.set_variable('ansible_python_interpreter',
                                 'PATH=/opt/bin:$PATH python')

            # 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)
コード例 #15
0
    def _parse_group_children(self):
        group = None

        for lineno in range(len(self.lines)):
            line = self.lines[lineno].strip()
            if line is None or line == '':
                continue
            if line.startswith("[") and ":children]" in line:
                line = line.replace("[", "").replace(":children]", "")
                group = self.groups.get(line, None)
                if group is None:
                    group = self.groups[line] = Group(name=line)
            elif line.startswith("#") or line.startswith(";"):
                pass
            elif line.startswith("["):
                group = None
            elif group:
                kid_group = self.groups.get(line, None)
                if kid_group is None:
                    raise errors.AnsibleError(
                        "%s:%d: child group is not defined: (%s)" %
                        (self.filename, lineno + 1, line))
                else:
                    group.add_child_group(kid_group)
コード例 #16
0
    def test_depth_update_dual_branches(self):
        alpha = Group('alpha')
        A = Group('A')
        alpha.add_child_group(A)
        B = Group('B')
        A.add_child_group(B)
        Z = Group('Z')
        alpha.add_child_group(Z)
        beta = Group('beta')
        B.add_child_group(beta)
        Z.add_child_group(beta)

        self.assertEqual(alpha.depth, 0)  # apex
        self.assertEqual(beta.depth, 3)  # alpha -> A -> B -> beta

        omega = Group('omega')
        omega.add_child_group(alpha)

        # verify that both paths are traversed to get the max depth value
        self.assertEqual(B.depth, 3)  # omega -> alpha -> A -> B
        self.assertEqual(beta.depth, 4)  # B -> beta
コード例 #17
0
ファイル: add_host.py プロジェクト: whiskybar/ansible
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):

        if self.runner.noop_on_check(inject):
            return ReturnData(
                conn=conn,
                comm_ok=True,
                result=dict(skipped=True,
                            msg='check mode not supported for this module'))

        args = {}
        if complex_args:
            args.update(complex_args)
        args.update(parse_kv(module_args))
        if not 'hostname' in args and not 'name' in args:
            raise ae("'name' is a required argument.")

        result = {}

        # Parse out any hostname:port patterns
        new_name = args.get('name', args.get('hostname', None))
        vv("creating host via 'add_host': hostname=%s" % new_name)

        if ":" in new_name:
            new_name, new_port = new_name.split(":")
            args['ansible_ssh_port'] = new_port

        # redefine inventory and get group "all"
        inventory = self.runner.inventory
        allgroup = inventory.get_group('all')

        # check if host in cache, add if not
        if new_name in inventory._hosts_cache:
            new_host = inventory._hosts_cache[new_name]
        else:
            new_host = Host(new_name)
            # only groups can be added directly to inventory
            inventory._hosts_cache[new_name] = new_host
            allgroup.add_host(new_host)

        # Add any variables to the new_host
        for k in args.keys():
            if not k in ['name', 'hostname', 'groupname', 'groups']:
                new_host.set_variable(k, args[k])

        groupnames = args.get('groupname',
                              args.get('groups', args.get('group', '')))
        # add it to the group if that was specified
        if groupnames != '':
            for group_name in groupnames.split(","):
                group_name = group_name.strip()
                if not inventory.get_group(group_name):
                    new_group = Group(group_name)
                    inventory.add_group(new_group)
                grp = inventory.get_group(group_name)
                grp.add_host(new_host)

                # add this host to the group cache
                if inventory._groups_list is not None:
                    if group_name in inventory._groups_list:
                        if new_host.name not in inventory._groups_list[
                                group_name]:
                            inventory._groups_list[group_name].append(
                                new_host.name)

                vv("added host to group via add_host module: %s" % group_name)
            result['new_groups'] = groupnames.split(",")

        result['new_host'] = new_name

        # clear pattern caching completely since it's unpredictable what
        # patterns may have referenced the group
        inventory.clear_pattern_cache()

        return ReturnData(conn=conn, comm_ok=True, result=result)
コード例 #18
0
    def __init__(self, host_list=C.DEFAULT_HOST_LIST):

        # the host file file, or script path, or list of hosts
        # if a list, inventory data will NOT be loaded
        self.host_list = host_list

        # caching to avoid repeated calculations, particularly with
        # external inventory scripts.

        self._vars_per_host = {}
        self._vars_per_group = {}
        self._hosts_cache = {}
        self._groups_list = {}
        self._pattern_cache = {}

        # to be set by calling set_playbook_basedir by ansible-playbook
        self._playbook_basedir = None

        # the inventory object holds a list of groups
        self.groups = []

        # a list of host(names) to contain current inquiries to
        self._restriction = None
        self._also_restriction = None
        self._subset = None

        if isinstance(host_list, basestring):
            if "," in host_list:
                host_list = host_list.split(",")
                host_list = [h for h in host_list if h and h.strip()]

        if host_list is None:
            self.parser = None
        elif isinstance(host_list, list):
            self.parser = None
            all = Group('all')
            self.groups = [all]
            ipv6_re = re.compile('\[([a-f:A-F0-9]*[%[0-z]+]?)\](?::(\d+))?')
            for x in host_list:
                m = ipv6_re.match(x)
                if m:
                    all.add_host(Host(m.groups()[0], m.groups()[1]))
                else:
                    if ":" in x:
                        tokens = x.rsplit(":", 1)
                        # if there is ':' in the address, then this is a ipv6
                        if ':' in tokens[0]:
                            all.add_host(Host(x))
                        else:
                            all.add_host(Host(tokens[0], tokens[1]))
                    else:
                        all.add_host(Host(x))
        elif os.path.exists(host_list):
            if os.path.isdir(host_list):
                # Ensure basedir is inside the directory
                self.host_list = os.path.join(self.host_list, "")
                self.parser = InventoryDirectory(filename=host_list)
                self.groups = self.parser.groups.values()
            elif utils.is_executable(host_list):
                self.parser = InventoryScript(filename=host_list)
                self.groups = self.parser.groups.values()
            else:
                self.parser = InventoryParser(filename=host_list)
                self.groups = self.parser.groups.values()

            utils.plugins.vars_loader.add_directory(self.basedir(),
                                                    with_subdir=True)
        else:
            raise errors.AnsibleError(
                "Unable to find an inventory file, specify one with -i ?")

        self._vars_plugins = [x for x in utils.plugins.vars_loader.all(self)]
コード例 #19
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
コード例 #20
0
    def __init__(self, host_list=C.DEFAULT_HOST_LIST):

        # the host file file, or script path, or list of hosts
        # if a list, inventory data will NOT be loaded
        self.host_list = host_list

        # caching to avoid repeated calculations, particularly with
        # external inventory scripts.

        self._vars_per_host = {}
        self._vars_per_group = {}
        self._hosts_cache = {}
        self._groups_list = {}

        # to be set by calling set_playbook_basedir by ansible-playbook
        self._playbook_basedir = None

        # the inventory object holds a list of groups
        self.groups = []

        # a list of host(names) to contain current inquiries to
        self._restriction = None
        self._also_restriction = None
        self._subset = None

        if isinstance(host_list, basestring):
            if "," in host_list:
                host_list = host_list.split(",")
                host_list = [h for h in host_list if h and h.strip()]

        if isinstance(host_list, list):
            self.parser = None
            all = Group('all')
            self.groups = [all]
            for x in host_list:
                if ":" in x:
                    tokens = x.split(":", 1)
                    all.add_host(Host(tokens[0], tokens[1]))
                else:
                    all.add_host(Host(x))
        elif os.path.exists(host_list):
            if os.path.isdir(host_list):
                # Ensure basedir is inside the directory
                self.host_list = os.path.join(self.host_list, "")
                self.parser = InventoryDirectory(filename=host_list)
                self.groups = self.parser.groups.values()
            elif utils.is_executable(host_list):
                self.parser = InventoryScript(filename=host_list)
                self.groups = self.parser.groups.values()
            else:
                data = file(host_list).read()
                if not data.startswith("---"):
                    self.parser = InventoryParser(filename=host_list)
                    self.groups = self.parser.groups.values()
                else:
                    raise errors.AnsibleError(
                        "YAML inventory support is deprecated in 0.6 and removed in 0.7, see the migration script in examples/scripts in the git checkout"
                    )

            utils.plugins.vars_loader.add_directory(self.basedir(),
                                                    with_subdir=True)
        else:
            raise errors.AnsibleError(
                "Unable to find an inventory file, specify one with -i ?")

        self._vars_plugins = [x for x in utils.plugins.vars_loader.all(self)]
コード例 #21
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)
コード例 #22
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)

        self.groups = dict(all=all, ungrouped=ungrouped)

        if host_list is None:
            pass
        elif isinstance(host_list, list):
            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
                all.add_host(new_host)
        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)
コード例 #23
0
ファイル: script.py プロジェクト: stacywsmith/ansible
    def _parse(self, err):

        all_hosts = {}

        # not passing from_remote because data from CMDB is trusted
        try:
            self.raw = self._loader.load(self.data)
        except Exception as e:
            sys.stderr.write(to_native(err) + "\n")
            raise AnsibleError(
                "failed to parse executable inventory script results from {0}: {1}"
                .format(to_native(self.filename), to_native(e)))

        if not isinstance(self.raw, Mapping):
            sys.stderr.write(to_native(err) + "\n")
            raise AnsibleError(
                "failed to parse executable inventory script results from {0}: data needs to be formatted "
                "as a json dict".format(to_native(self.filename)))

        group = None
        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 not in self.groups:
                group = self.groups[group_name] = Group(group_name)

            group = self.groups[group_name]
            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', 'children')):
                data = {'hosts': [group_name], 'vars': data}

            if 'hosts' in data:
                if not isinstance(data['hosts'], list):
                    raise AnsibleError("You defined a group \"%s\" with bad "
                                       "data for the host list:\n %s" %
                                       (group_name, data))

                for hostname in data['hosts']:
                    if hostname not 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 AnsibleError("You defined a group \"%s\" with bad "
                                       "data for variables:\n %s" %
                                       (group_name, data))

                for k, v in iteritems(data['vars']):
                    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 self.groups:
                        self.groups[group_name].add_child_group(
                            self.groups[child_name])

        # Finally, add all top-level groups as children of 'all'.
        # We exclude ungrouped here because it was already added as a child of
        # 'all' at the time it was created.

        for group in self.groups.values():
            if group.depth == 0 and group.name not in ('all', 'ungrouped'):
                self.groups['all'].add_child_group(group)
コード例 #24
0
ファイル: __init__.py プロジェクト: xuyeli2002/ansible
    def __init__(self, loader, variable_manager, host_list=C.DEFAULT_HOST_LIST):

        # the host file file, or script path, or list of hosts
        # if a list, inventory data will NOT be loaded
        self.host_list = host_list
        self._loader = loader
        self._variable_manager = variable_manager

        # caching to avoid repeated calculations, particularly with
        # external inventory scripts.

        self._vars_per_host  = {}
        self._vars_per_group = {}
        self._hosts_cache    = {}
        self._groups_list    = {} 
        self._pattern_cache  = {}

        # to be set by calling set_playbook_basedir by playbook code
        self._playbook_basedir = None

        # the inventory object holds a list of groups
        self.groups = []

        # a list of host(names) to contain current inquiries to
        self._restriction = None
        self._also_restriction = None
        self._subset = None

        if isinstance(host_list, basestring):
            if "," in host_list:
                host_list = host_list.split(",")
                host_list = [ h for h in host_list if h and h.strip() ]

        if host_list is None:
            self.parser = None
        elif isinstance(host_list, list):
            self.parser = None
            all = Group('all')
            self.groups = [ all ]
            ipv6_re = re.compile('\[([a-f:A-F0-9]*[%[0-z]+]?)\](?::(\d+))?')
            for x in host_list:
                m = ipv6_re.match(x)
                if m:
                    all.add_host(Host(m.groups()[0], m.groups()[1]))
                else:
                    if ":" in x:
                        tokens = x.rsplit(":", 1)
                        # if there is ':' in the address, then this is an ipv6
                        if ':' in tokens[0]:
                            all.add_host(Host(x))
                        else:
                            all.add_host(Host(tokens[0], tokens[1]))
                    else:
                        all.add_host(Host(x))
        elif os.path.exists(host_list):
            if os.path.isdir(host_list):
                # Ensure basedir is inside the directory
                self.host_list = os.path.join(self.host_list, "")
                self.parser = InventoryDirectory(loader=self._loader, filename=host_list)
                self.groups = self.parser.groups.values()
            else:
                # check to see if the specified file starts with a
                # shebang (#!/), so if an error is raised by the parser
                # class we can show a more apropos error
                shebang_present = False
                try:
                    inv_file = open(host_list)
                    first_line = inv_file.readlines()[0]
                    inv_file.close()
                    if first_line.startswith('#!'):
                        shebang_present = True
                except:
                    pass

                if is_executable(host_list):
                    try:
                        self.parser = InventoryScript(loader=self._loader, filename=host_list)
                        self.groups = self.parser.groups.values()
                    except:
                        if not shebang_present:
                            raise errors.AnsibleError("The file %s is marked as executable, but failed to execute correctly. " % host_list + \
                                                      "If this is not supposed to be an executable script, correct this with `chmod -x %s`." % host_list)
                        else:
                            raise
                else:
                    try:
                        self.parser = InventoryParser(filename=host_list)
                        self.groups = self.parser.groups.values()
                    except:
                        if shebang_present:
                            raise errors.AnsibleError("The file %s looks like it should be an executable inventory script, but is not marked executable. " % host_list + \
                                                      "Perhaps you want to correct this with `chmod +x %s`?" % host_list)
                        else:
                            raise

            vars_loader.add_directory(self.basedir(), with_subdir=True)
        else:
            raise errors.AnsibleError("Unable to find an inventory file, specify one with -i ?")

        self._vars_plugins = [ x for x in vars_loader.all(self) ]

        # FIXME: shouldn't be required, since the group/host vars file
        #        management will be done in VariableManager
        # get group vars from group_vars/ files and vars plugins
        for group in self.groups:
            # FIXME: combine_vars
            group.vars = combine_vars(group.vars, self.get_group_variables(group.name))

        # get host vars from host_vars/ files and vars plugins
        for host in self.get_hosts():
            # FIXME: combine_vars
            host.vars = combine_vars(host.vars, self.get_host_variables(host.name))
コード例 #25
0
    def _parse(self, lines):
        '''
        Populates self.groups from the given array of lines. Raises an error on
        any parse failure.
        '''

        self._compile_patterns()

        # We behave as though the first line of the inventory is '[ungrouped]',
        # and begin to look for host definitions. We make a single pass through
        # each line of the inventory, building up self.groups and adding hosts,
        # subgroups, and setting variables as we go.

        pending_declarations = {}
        groupname = 'ungrouped'
        state = 'hosts'

        self.lineno = 0
        for line in lines:
            self.lineno += 1

            line = line.strip()

            # Skip empty lines and comments
            if not line or line[0] in self._COMMENT_MARKERS:
                continue

            # Is this a [section] header? That tells us what group we're parsing
            # definitions for, and what kind of definitions to expect.

            m = self.patterns['section'].match(line)
            if m:
                (groupname, state) = m.groups()

                state = state or 'hosts'
                if state not in ['hosts', 'children', 'vars']:
                    title = ":".join(m.groups())
                    self._raise_error("Section [%s] has unknown type: %s" %
                                      (title, state))

                # If we haven't seen this group before, we add a new Group.
                #
                # Either [groupname] or [groupname:children] is sufficient to
                # declare a group, but [groupname:vars] is allowed only if the
                # group is declared elsewhere (not necessarily earlier). We add
                # the group anyway, but make a note in pending_declarations to
                # check at the end.

                if groupname not in self.groups:
                    self.groups[groupname] = Group(name=groupname)

                    if state == 'vars':
                        pending_declarations[groupname] = dict(
                            line=self.lineno, state=state, name=groupname)

                # When we see a declaration that we've been waiting for, we can
                # delete the note.

                if groupname in pending_declarations and state != 'vars':
                    del pending_declarations[groupname]

                continue
            elif line.startswith('[') and line.endswith(']'):
                self._raise_error(
                    "Invalid section entry: '%s'. Please make sure that there are no spaces"
                    % line +
                    "in the section entry, and that there are no other invalid characters"
                )

            # It's not a section, so the current state tells us what kind of
            # definition it must be. The individual parsers will raise an
            # error if we feed them something they can't digest.

            # [groupname] contains host definitions that must be added to
            # the current group.
            if state == 'hosts':
                hosts = self._parse_host_definition(line)
                for h in hosts:
                    self.groups[groupname].add_host(h)

            # [groupname:vars] contains variable definitions that must be
            # applied to the current group.
            elif state == 'vars':
                (k, v) = self._parse_variable_definition(line)
                if k != 'ansible_group_priority':
                    self.groups[groupname].set_variable(k, v)
                else:
                    self.groups[groupname].set_priority(v)

            # [groupname:children] contains subgroup names that must be
            # added as children of the current group. The subgroup names
            # must themselves be declared as groups, but as before, they
            # may only be declared later.
            elif state == 'children':
                child = self._parse_group_name(line)

                if child not in self.groups:
                    self.groups[child] = Group(name=child)
                    pending_declarations[child] = dict(line=self.lineno,
                                                       state=state,
                                                       name=child,
                                                       parent=groupname)

                self.groups[groupname].add_child_group(self.groups[child])

                # Note: there's no reason why we couldn't accept variable
                # definitions here, and set them on the named child group.

            # This is a fencepost. It can happen only if the state checker
            # accepts a state that isn't handled above.
            else:
                self._raise_error("Entered unhandled state: %s" % (state))

        # Any entries in pending_declarations not removed by a group declaration
        # above mean that there was an unresolved forward reference. We report
        # only the first such error here.

        for g in pending_declarations:
            decl = pending_declarations[g]
            if decl['state'] == 'vars':
                raise AnsibleError(
                    "%s:%d: Section [%s:vars] not valid for undefined group: %s"
                    %
                    (self.filename, decl['line'], decl['name'], decl['name']))
            elif decl['state'] == 'children':
                raise AnsibleError(
                    "%s:%d: Section [%s:children] includes undefined group: %s"
                    % (self.filename, decl['line'], decl['parent'],
                       decl['name']))

        # Finally, add all top-level groups as children of 'all'.
        # We exclude ungrouped here because it was already added as a child of
        # 'all' at the time it was created.

        for group in self.groups.values():
            if group.depth == 0 and group.name not in ('all', 'ungrouped'):
                self.groups['all'].add_child_group(group)
コード例 #26
0
    def _parse_base_groups(self):
        # FIXME: refactor

        ungrouped = Group(name='ungrouped')
        all = Group(name='all')
        all.add_child_group(ungrouped)

        self.groups = dict(all=all, ungrouped=ungrouped)
        active_group_name = 'ungrouped'

        for line in self.lines:
            line = line.split("#")[0].strip()
            if line.startswith("[") and line.endswith("]"):
                active_group_name = line.replace("[", "").replace("]", "")
                if line.find(":vars") != -1 or line.find(":children") != -1:
                    active_group_name = active_group_name.rsplit(":", 1)[0]
                    if active_group_name not in self.groups:
                        new_group = self.groups[active_group_name] = Group(
                            name=active_group_name)
                        all.add_child_group(new_group)
                    active_group_name = None
                elif active_group_name not in self.groups:
                    new_group = self.groups[active_group_name] = Group(
                        name=active_group_name)
                    all.add_child_group(new_group)
            elif line.startswith(";") or line == '':
                pass
            elif active_group_name:
                tokens = shlex.split(line)
                if len(tokens) == 0:
                    continue
                hostname = tokens[0]
                port = C.DEFAULT_REMOTE_PORT
                # Three cases to check:
                # 0. A hostname that contains a range pesudo-code and a port
                # 1. A hostname that contains just a port
                if hostname.count(":") > 1:
                    # probably an IPv6 addresss, so check for the format
                    # XXX:XXX::XXX.port, otherwise we'll just assume no
                    # port is set
                    if hostname.find(".") != -1:
                        (hostname, port) = hostname.rsplit(".", 1)
                elif (hostname.find("[") != -1 and hostname.find("]") != -1
                      and hostname.find(":") != -1 and
                      (hostname.rindex("]") < hostname.rindex(":")) or
                      (hostname.find("]") == -1 and hostname.find(":") != -1)):
                    (hostname, port) = hostname.rsplit(":", 1)

                hostnames = []
                if detect_range(hostname):
                    hostnames = expand_hostname_range(hostname)
                else:
                    hostnames = [hostname]

                for hn in hostnames:
                    host = None
                    if hn in self.hosts:
                        host = self.hosts[hn]
                    else:
                        host = Host(name=hn, port=port)
                        self.hosts[hn] = host
                    if len(tokens) > 1:
                        for t in tokens[1:]:
                            if t.startswith('#'):
                                break
                            try:
                                (k, v) = t.split("=")
                            except ValueError, e:
                                raise errors.AnsibleError(
                                    "Invalid ini entry: %s - %s" % (t, str(e)))
                            try:
                                host.set_variable(k, ast.literal_eval(v))
                            except:
                                # most likely a string that literal_eval
                                # doesn't like, so just set it
                                host.set_variable(k, v)
                    self.groups[active_group_name].add_host(host)
コード例 #27
0
    def _parse_base_groups(self):
        # FIXME: refactor

        ungrouped = Group(name='ungrouped')
        all = Group(name='all')
        all.add_child_group(ungrouped)

        self.groups = dict(all=all, ungrouped=ungrouped)
        active_group_name = 'ungrouped'

        for line in self.lines:
            line = utils.before_comment(line).strip()
            if line.startswith("[") and line.endswith("]"):
                active_group_name = line.replace("[", "").replace("]", "")
                if ":vars" in line or ":children" in line:
                    active_group_name = active_group_name.rsplit(":", 1)[0]
                    if active_group_name not in self.groups:
                        new_group = self.groups[active_group_name] = Group(
                            name=active_group_name)
                    active_group_name = None
                elif active_group_name not in self.groups:
                    new_group = self.groups[active_group_name] = Group(
                        name=active_group_name)
            elif line.startswith(";") or line == '':
                pass
            elif active_group_name:
                tokens = shlex.split(line)
                if len(tokens) == 0:
                    continue
                hostname = tokens[0]
                port = C.DEFAULT_REMOTE_PORT
                # Three cases to check:
                # 0. A hostname that contains a range pesudo-code and a port
                # 1. A hostname that contains just a port
                if hostname.count(":") > 1:
                    # Possible an IPv6 address, or maybe a host line with multiple ranges
                    # IPv6 with Port  XXX:XXX::XXX.port
                    # FQDN            foo.example.com
                    if hostname.count(".") == 1:
                        (hostname, port) = hostname.rsplit(".", 1)
                elif ("[" in hostname and "]" in hostname and ":" in hostname
                      and (hostname.rindex("]") < hostname.rindex(":"))
                      or ("]" not in hostname and ":" in hostname)):
                    (hostname, port) = hostname.rsplit(":", 1)

                hostnames = []
                if detect_range(hostname):
                    hostnames = expand_hostname_range(hostname)
                else:
                    hostnames = [hostname]

                for hn in hostnames:
                    host = None
                    if hn in self.hosts:
                        host = self.hosts[hn]
                    else:
                        host = Host(name=hn, port=port)
                        self.hosts[hn] = host
                    if len(tokens) > 1:
                        for t in tokens[1:]:
                            if t.startswith('#'):
                                break
                            try:
                                (k, v) = t.split("=", 1)
                            except ValueError, e:
                                raise errors.AnsibleError(
                                    "Invalid ini entry: %s - %s" % (t, str(e)))
                            host.set_variable(k, self._parse_value(v))
                    self.groups[active_group_name].add_host(host)
コード例 #28
0
ファイル: script.py プロジェクト: yanc0/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

            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}
            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
コード例 #29
0
    def run(self):
        # insert node
        for ip in self.hosts:
            self._node_map[ip] = Service.new_node(self.task_id, ip)

        variable_manager = VariableManager()

        Logger.debug("start write ssh_key for task: {} global_id : {}".format(
            self.task_id, self.global_id))

        key_files = []

        group = Group(self.task_id)

        for h in self.hosts:

            # get ssh_key content
            key_content = _get_ssh_key(h)

            Logger.debug("read ssh_key for host: {} global_id: {}".format(
                h, self.global_id))

            # write ssh private key
            key_path = _write_ssh_key(h, key_content)

            #key_path="./tmp/97"
            Logger.debug("write ssh_key for host: {} global_id: {}".format(
                h, self.global_id))

            host_vars = dict(ansible_port=22,
                             ansible_user=self.user,
                             ansible_ssh_private_key_file="./" + key_path)

            Logger.debug("key_path: {} global_id: {}".format(
                key_path, self.global_id))

            key_files.append(key_path)

            host = Host(h)

            host.vars = host_vars

            group.add_host(host)

        # add params to each host
        if self.params is not None and isinstance(self.params, dict):
            for h in group.hosts:
                for key in self.params.keys():
                    variable_manager.set_host_variable(h, key,
                                                       self.params[key])

        Logger.debug("success write ssh_key for task: {} global_id: {}".format(
            self.task_id, self.global_id))

        # other options
        ssh_args = '-oControlMaster=auto -oControlPersist=60s -oStrictHostKeyChecking=no'
        options = _Options(connection='ssh',
                           module_path='./ansible/library',
                           forks=self.forks,
                           timeout=10,
                           remote_user=None,
                           private_key_file=None,
                           ssh_common_args=ssh_args,
                           ssh_extra_args=None,
                           sftp_extra_args=None,
                           scp_extra_args=None,
                           become=None,
                           become_method=None,
                           become_user=None,
                           verbosity=None,
                           check=False)

        if self.tasktype == "ansible_task":
            Logger.debug(
                "ansible tasks set*******************  global_id: {}".format(
                    self.global_id))
            play_source = dict(name=self.task_id,
                               hosts=self.task_id,
                               gather_facts='yes',
                               tasks=self.tasks)
        else:

            Logger.debug(
                "ansible role set******************* global_id: {}".format(
                    self.global_id))
            play_source = dict(name=self.task_id,
                               hosts=self.task_id,
                               gather_facts='yes',
                               roles=self.tasks)

        Logger.debug("start load play for task: {} global_id: {}".format(
            self.task_id, self.global_id))

        # make playbook
        playbook = Play().load(play_source,
                               variable_manager=variable_manager,
                               loader=_Loader)

        inventory = Inventory(loader=_Loader,
                              variable_manager=variable_manager)

        inventory.add_group(group)

        call_back = SyncCallbackModule(debug=True,
                                       step_callback=self._step_callback,
                                       global_id=self.global_id,
                                       source=self.source,
                                       tag_hosts=self.hosts)

        Logger.debug("success load play for task: {} global_id: {}".format(
            self.task_id, self.global_id))

        # task queue
        tqm = TaskQueueManager(inventory=inventory,
                               variable_manager=variable_manager,
                               loader=_Loader,
                               options=options,
                               passwords=None,
                               stdout_callback=call_back)

        try:
            back = tqm.run(playbook)

            Logger.info("back: {} global_id : {}".format(
                str(back), self.global_id))

            if back != 0:
                raise Exception("playbook run failed")

            return back
        finally:
            if tqm is not None:
                tqm.cleanup()
                _rm_tmp_key(key_files)
コード例 #30
0
    def run(self,
            conn,
            tmp,
            module_name,
            module_args,
            inject,
            complex_args=None,
            **kwargs):

        if self.runner.check:
            return ReturnData(
                conn=conn,
                comm_ok=True,
                result=dict(skipped=True,
                            msg='check mode not supported for this module'))

        args = {}
        if complex_args:
            args.update(complex_args)
        args.update(parse_kv(module_args))
        if not 'hostname' in args and not 'name' in args:
            raise ae("'name' is a required argument.")

        result = {'changed': True}

        # Parse out any hostname:port patterns
        new_hostname = args.get('hostname', args.get('name', None))
        vv("creating host via 'add_host': hostname=%s" % new_hostname)

        if ":" in new_hostname:
            new_hostname, new_port = new_hostname.split(":")
            args['ansible_ssh_port'] = new_port

        # create host and get inventory
        new_host = Host(new_hostname)
        inventory = self.runner.inventory

        # Add any variables to the new_host
        for k in args.keys():
            if not k in ['name', 'hostname', 'groupname', 'groups']:
                new_host.set_variable(k, args[k])

        # add the new host to the 'all' group
        allgroup = inventory.get_group('all')
        allgroup.add_host(new_host)
        result['changed'] = True

        groupnames = args.get('groupname', args.get('groups', ''))
        # add it to the group if that was specified
        if groupnames != '':
            for group_name in groupnames.split(","):
                if not inventory.get_group(group_name):
                    new_group = Group(group_name)
                    inventory.add_group(new_group)
                grp = inventory.get_group(group_name)
                grp.add_host(new_host)
            vv("added host to group via add_host module: %s" % group_name)
            result['new_groups'] = groupnames.split(",")

        result['new_host'] = new_hostname

        return ReturnData(conn=conn, comm_ok=True, result=result)