def read_vault_password_file(vault_password_file): """ Read a vault password from a file or if executable, execute the script and retrieve password from STDOUT """ this_path = os.path.realpath(os.path.expanduser(vault_password_file)) if not os.path.exists(this_path): raise AnsibleError("The vault password file %s was not found" % this_path) if is_executable(this_path): try: # STDERR not captured to make it easier for users to prompt for input in their scripts p = subprocess.Popen(this_path, stdout=subprocess.PIPE) except OSError as e: raise AnsibleError( "Problem running vault password script %s (%s). If this is not a script, remove the executable bit from the file." % (' '.join(this_path), e)) stdout, stderr = p.communicate() vault_pass = stdout.strip('\r\n') else: try: f = open(this_path, "rb") vault_pass = f.read().strip() f.close() except (OSError, IOError) as e: raise AnsibleError( "Could not read vault password file %s: %s" % (this_path, e)) return vault_pass
def read_vault_file(vault_password_file): """ Read a vault password from a file or if executable, execute the script and retrieve password from STDOUT """ this_path = os.path.realpath(os.path.expanduser(vault_password_file)) if not os.path.exists(this_path): raise AnsibleError("The vault password file %s was not found" % this_path) if is_executable(this_path): try: # STDERR not captured to make it easier for users to prompt for input in their scripts p = subprocess.Popen(this_path, stdout=subprocess.PIPE) except OSError as e: raise AnsibleError("Problem running vault password script %s (%s). If this is not a script, remove the executable bit from the file." % (' '.join(this_path), e)) stdout, stderr = p.communicate() vault_pass = stdout.strip('\r\n') else: try: f = open(this_path, "rb") vault_pass=f.read().strip() f.close() except (OSError, IOError) as e: raise AnsibleError("Could not read vault password file %s: %s" % (this_path, e)) return vault_pass
def get_file_parser(hostsfile, loader): # 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 processed = False myerr = [] parser = None try: inv_file = open(hostsfile) first_line = inv_file.readlines()[0] inv_file.close() if first_line.startswith('#!'): shebang_present = True except: pass if is_executable(hostsfile): try: parser = InventoryScript(loader=loader, filename=hostsfile) processed = True except Exception as e: myerr.append("The file %s is marked as executable, but failed to execute correctly. " % hostsfile + \ "If this is not supposed to be an executable script, correct this with `chmod -x %s`." % hostsfile) myerr.append(str(e)) if not processed: try: parser = InventoryINIParser(filename=hostsfile) processed = True except Exception as e: if shebang_present and not is_executable(hostsfile): myerr.append("The file %s looks like it should be an executable inventory script, but is not marked executable. " % hostsfile + \ "Perhaps you want to correct this with `chmod +x %s`?" % hostsfile) else: myerr.append(str(e)) if not processed and myerr: raise AnsibleError('\n'.join(myerr)) return parser
def __init__(self, *args, **kwargs): super(Connection, self).__init__(*args, **kwargs) self.chroot = self._play_context.remote_addr if os.geteuid() != 0: raise AnsibleError("chroot connection requires running as root") # we're running as root on the local system so do some # trivial checks for ensuring 'host' is actually a chroot'able dir if not os.path.isdir(self.chroot): raise AnsibleError("%s is not a directory" % self.chroot) chrootsh = os.path.join(self.chroot, "bin/sh") if not is_executable(chrootsh): raise AnsibleError("%s does not look like a chrootable dir (/bin/sh missing)" % self.chroot) self.chroot_cmd = distutils.spawn.find_executable("chroot") if not self.chroot_cmd: raise AnsibleError("chroot command not found in PATH")
def __init__(self, *args, **kwargs): super(Connection, self).__init__(*args, **kwargs) self.chroot = self._play_context.remote_addr if os.geteuid() != 0: raise AnsibleError("chroot connection requires running as root") # we're running as root on the local system so do some # trivial checks for ensuring 'host' is actually a chroot'able dir if not os.path.isdir(self.chroot): raise AnsibleError("%s is not a directory" % self.chroot) chrootsh = os.path.join(self.chroot, 'bin/sh') if not is_executable(chrootsh): raise AnsibleError( "%s does not look like a chrootable dir (/bin/sh missing)" % self.chroot) self.chroot_cmd = distutils.spawn.find_executable('chroot') if not self.chroot_cmd: raise AnsibleError("chroot command not found in PATH")
def __init__(self, loader, filename=C.DEFAULT_HOST_LIST): self.names = os.listdir(filename) self.names.sort() self.directory = filename self.parsers = [] self.hosts = {} self.groups = {} self._loader = loader for i in self.names: # Skip files that end with certain extensions or characters if any(i.endswith(ext) for ext in ("~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo")): continue # Skip hidden files if i.startswith('.') and not i.startswith('./'): 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(loader=loader, filename=fullpath) elif is_executable(fullpath): parser = InventoryScript(loader=loader, filename=fullpath) else: parser = InventoryParser(filename=fullpath) self.parsers.append(parser) # retrieve all groups and hosts form the parser and add them to # self, don't look at group lists yet, to avoid # recursion trouble, but just make sure all objects exist in self newgroups = parser.groups.values() for group in newgroups: for host in group.hosts: self._add_host(host) for group in newgroups: self._add_group(group) # now check the objects lists so they contain only objects from # self; membership data in groups is already fine (except all & # ungrouped, see later), but might still reference objects not in self for group in self.groups.values(): # iterate on a copy of the lists, as those lists get changed in # the loop # list with group's child group objects: for child in group.child_groups[:]: if child != self.groups[child.name]: group.child_groups.remove(child) group.child_groups.append(self.groups[child.name]) # list with group's parent group objects: for parent in group.parent_groups[:]: if parent != self.groups[parent.name]: group.parent_groups.remove(parent) group.parent_groups.append(self.groups[parent.name]) # list with group's host objects: for host in group.hosts[:]: if host != self.hosts[host.name]: group.hosts.remove(host) group.hosts.append(self.hosts[host.name]) # also check here that the group that contains host, is # also contained in the host's group list if group not in self.hosts[host.name].groups: self.hosts[host.name].groups.append(group) # extra checks on special groups all and ungrouped # remove hosts from 'ungrouped' if they became member of other groups if 'ungrouped' in self.groups: ungrouped = self.groups['ungrouped'] # loop on a copy of ungrouped hosts, as we want to change that list for host in ungrouped.hosts[:]: if len(host.groups) > 1: host.groups.remove(ungrouped) ungrouped.hosts.remove(host) # remove hosts from 'all' if they became member of other groups # all should only contain direct children, not grandchildren # direct children should have dept == 1 if 'all' in self.groups: allgroup = self.groups['all' ] # loop on a copy of all's child groups, as we want to change that list for group in allgroup.child_groups[:]: # groups might once have beeen added to all, and later be added # to another group: we need to remove the link wit all then if len(group.parent_groups) > 1 and allgroup in group.parent_groups: # real children of all have just 1 parent, all # this one has more, so not a direct child of all anymore group.parent_groups.remove(allgroup) allgroup.child_groups.remove(group) elif allgroup not in group.parent_groups: # this group was once added to all, but doesn't list it as # a parent any more; the info in the group is the correct # info allgroup.child_groups.remove(group)
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 __init__(self, loader, filename=C.DEFAULT_HOST_LIST): self.names = os.listdir(filename) self.names.sort() self.directory = filename self.parsers = [] self.hosts = {} self.groups = {} self._loader = loader for i in self.names: # Skip files that end with certain extensions or characters if any( i.endswith(ext) for ext in ("~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo")): continue # Skip hidden files if i.startswith('.') and not i.startswith('./'): 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(loader=loader, filename=fullpath) elif is_executable(fullpath): parser = InventoryScript(loader=loader, filename=fullpath) else: parser = InventoryParser(filename=fullpath) self.parsers.append(parser) # retrieve all groups and hosts form the parser and add them to # self, don't look at group lists yet, to avoid # recursion trouble, but just make sure all objects exist in self newgroups = parser.groups.values() for group in newgroups: for host in group.hosts: self._add_host(host) for group in newgroups: self._add_group(group) # now check the objects lists so they contain only objects from # self; membership data in groups is already fine (except all & # ungrouped, see later), but might still reference objects not in self for group in self.groups.values(): # iterate on a copy of the lists, as those lists get changed in # the loop # list with group's child group objects: for child in group.child_groups[:]: if child != self.groups[child.name]: group.child_groups.remove(child) group.child_groups.append(self.groups[child.name]) # list with group's parent group objects: for parent in group.parent_groups[:]: if parent != self.groups[parent.name]: group.parent_groups.remove(parent) group.parent_groups.append(self.groups[parent.name]) # list with group's host objects: for host in group.hosts[:]: if host != self.hosts[host.name]: group.hosts.remove(host) group.hosts.append(self.hosts[host.name]) # also check here that the group that contains host, is # also contained in the host's group list if group not in self.hosts[host.name].groups: self.hosts[host.name].groups.append(group) # extra checks on special groups all and ungrouped # remove hosts from 'ungrouped' if they became member of other groups if 'ungrouped' in self.groups: ungrouped = self.groups['ungrouped'] # loop on a copy of ungrouped hosts, as we want to change that list for host in ungrouped.hosts[:]: if len(host.groups) > 1: host.groups.remove(ungrouped) ungrouped.hosts.remove(host) # remove hosts from 'all' if they became member of other groups # all should only contain direct children, not grandchildren # direct children should have dept == 1 if 'all' in self.groups: allgroup = self.groups['all'] # loop on a copy of all's child groups, as we want to change that list for group in allgroup.child_groups[:]: # groups might once have beeen added to all, and later be added # to another group: we need to remove the link wit all then if len(group.parent_groups ) > 1 and allgroup in group.parent_groups: # real children of all have just 1 parent, all # this one has more, so not a direct child of all anymore group.parent_groups.remove(allgroup) allgroup.child_groups.remove(group) elif allgroup not in group.parent_groups: # this group was once added to all, but doesn't list it as # a parent any more; the info in the group is the correct # info allgroup.child_groups.remove(group)