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(name='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_unicode(e)) host = h port = None 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.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) self._vars_plugins = [x for x in vars_loader.all(self)] # get group vars from group_vars/ files and vars plugins for group in self.groups.values(): 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))
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()] 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): #TODO: switch this to a plugin loader and a 'condition' per plugin on which it should be tried, restoring 'inventory pllugins' if os.path.isdir(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))
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_unicode(e)) host = h port = None 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.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_unicode(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)) # set 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))
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()] 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 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))
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(name='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: (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, 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) 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.values(): 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))
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))
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))
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)
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 add the implicit 'localhost' to it. ungrouped = Group('ungrouped') all = Group('all') all.add_child_group(ungrouped) base_groups = frozenset([all, 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) ] ### POST PROCESS groups and hosts after specific parser was invoked group_names = set() # 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) group_names.add(group.name) host_names = set() # 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) host_names.add(host.name) mygroups = host.get_groups() # ensure hosts are always in 'all' if all not in mygroups: all.add_host(host) if ungrouped in mygroups: # clear ungrouped of any incorrectly stored by parser if set(mygroups).difference(base_groups): host.remove_group(ungrouped) else: # add ungrouped hosts to ungrouped length = len(mygroups) if length == 0 or (length == 1 and all in mygroups): ungrouped.add_host(host) # warn if overloading identifier as both group and host for conflict in group_names.intersection(host_names): display.warning("Found both group and host with same name: %s" % conflict)