def _libvirt_init_config(): x("yum install augeas -y") #Initialize augeas augeas = Augeas(x) augeas.set_enhanced("/files/etc/sysconfig/libvirt-guests/ON_SHUTDOWN","shutdown")
def match(path, value=''): ''' Get matches for path expression CLI Example:: salt '*' augeas.match /files/etc/services/service-name ssh ''' from augeas import Augeas aug = Augeas() ret = {} try: matches = aug.match(path) except RuntimeError: return ret for _match in matches: if value and aug.get(_match) == value: ret[_match] = value elif not value: ret[_match] = aug.get(_match) return ret
def get(path, value=""): """ Get a value for a specific augeas path CLI Example:: salt '*' augeas.get /files/etc/hosts/1/ ipaddr """ from augeas import Augeas aug = Augeas() ret = {} path = path.rstrip("/") if value: path += "/{0}".format(value.strip("/")) try: _match = aug.match(path) except RuntimeError as err: return {"error": str(err)} if _match: ret[path] = aug.get(path) else: ret[path] = "" # node does not exist return ret
def setvalue(*args): ''' Set a value for a specific augeas path CLI Example:: salt '*' augeas.setvalue /files/etc/hosts/1/canonical localhost This will set the first entry in /etc/hosts to localhost CLI Example:: salt '*' augeas.setvalue /files/etc/hosts/01/ipaddr 192.168.1.1 \\ /files/etc/hosts/01/canonical test Adds a new host to /etc/hosts the ip address 192.168.1.1 and hostname test CLI Example:: salt '*' augeas.setvalue prefix=/files/etc/sudoers/ \\ "spec[user = '******']/user" "%wheel" \\ "spec[user = '******']/host_group/host" 'ALL' \\ "spec[user = '******']/host_group/command[1]" 'ALL' \\ "spec[user = '******']/host_group/command[1]/tag" 'PASSWD' \\ "spec[user = '******']/host_group/command[2]" '/usr/bin/apt-get' \\ "spec[user = '******']/host_group/command[2]/tag" NOPASSWD Ensures that the following line is present in /etc/sudoers:: %wheel ALL = PASSWD : ALL , NOPASSWD : /usr/bin/apt-get , /usr/bin/aptitude ''' aug = Augeas() ret = {'retval': False} tuples = filter(lambda x: not x.startswith('prefix='), args) prefix = filter(lambda x: x.startswith('prefix='), args) if prefix: prefix = prefix[0].split('=', 1)[1] if len(tuples) % 2 != 0: return ret # ensure we have multiple of twos tuple_iter = iter(tuples) for path, value in zip(tuple_iter, tuple_iter): target_path = path if prefix: target_path = "{0}/{1}".format(prefix.rstrip('/'), path.lstrip('/')) try: aug.set(target_path, str(value)) except ValueError as err: ret['error'] = "Multiple values: " + str(err) try: aug.save() ret['retval'] = True except IOError as err: ret['error'] = str(err) return ret
def install_syco(args): """ Install/configure this script on the current computer. """ app.print_verbose("Install syco version: %d" % SCRIPT_VERSION) version_obj = version.Version("InstallSYCO", SCRIPT_VERSION) version_obj.check_executed() #Override base repo to one that works x("cat %syum/CentOS-Base.repo > /etc/yum.repos.d/CentOS-Base.repo" % app.SYCO_VAR_PATH) #Set Swappiness to 0 on all hosts to avoid excessive swapping x('sysctl vm.swappiness=0') app.print_verbose("Install required packages for syco") x("yum install augeas -y") app.print_verbose("Create symlink /sbin/syco") set_syco_permissions() if not os.path.exists('/sbin/syco'): os.symlink('%sbin/syco.py' % SYCO_PATH, '/sbin/syco') #Use augeas to set max kernels to 2 since more won't fit on /boot from augeas import Augeas augeas = Augeas(x) augeas.set_enhanced("/files/etc/yum.conf/main/installonly_limit", "2") version_obj.mark_executed()
def install_syco(args): """ Install/configure this script on the current computer. """ app.print_verbose("Install syco version: %d" % SCRIPT_VERSION) version_obj = version.Version("InstallSYCO", SCRIPT_VERSION) version_obj.check_executed() app.print_verbose("Install required packages for syco") x("yum install pexpect python-crypto augeas -y") app.print_verbose("Create symlink /sbin/syco") set_syco_permissions() if not os.path.exists('/sbin/syco'): os.symlink('%sbin/syco.py' % SYCO_PATH, '/sbin/syco') x("cat %syum/CentOS-Base.repo > /etc/yum.repos.d/CentOS-Base.repo" % app.SYCO_VAR_PATH) #Use augeas to set max kernels to 2 since more won't fit on /boot from augeas import Augeas augeas = Augeas(x) augeas.set_enhanced("/files/etc/yum.conf/main/installonly_limit", "2") version_obj.mark_executed()
def get(self,entryPath,param='',hierarchy='/files'): """Get a value for a config. parameter in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) # yes, entryPath.rstrip('/')+'/' is really needed (i.e. entryPath=/) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') try: matchtest=aug.match(path) except Exception, e: return str(e) if matchtest: try: pvalue=aug.get(path) #aug.close() except Exception, e: return str(e) else: # The node doesn't exist pvalue='(o)' if not pvalue: # The node doesn't have a value pvalue='(none)' return { 'path': entryPath, 'parameter': param, 'value': pvalue, 'hierarchy': hierarchy }
def get(path, value=''): ''' Get a value for a specific augeas path CLI Example:: salt '*' augeas.get /files/etc/hosts/1/ ipaddr ''' from augeas import Augeas aug = Augeas() ret = {} path = path.rstrip('/') if value: path += "/{0}".format(value.strip('/')) try: _match = aug.match(path) except RuntimeError as err: return {'error': str(err)} if _match: ret[path] = aug.get(path) else: ret[path] = '' # node does not exist return ret
def remove(path): ''' Get matches for path expression CLI Example:: salt '*' augeas.remove /files/etc/sysctl.conf/net.ipv4.conf.all.log_martians ''' from augeas import Augeas aug = Augeas() ret = {'retval': False} try: count = aug.remove(path) aug.save() if count == -1: ret['error'] = 'Invalid node' else: ret['retval'] = True except (RuntimeError, IOError) as err: ret['error'] = str(err) ret['count'] = count return ret
def create_sample_config(context, service): service = service.strip() # Create parser parser = Augeas(root=getattr(context, 'AUGEAS_ROOT'), loadpath=os.path.join(getattr(context, 'AUGEAS_LENS_LIB'), '{}_lens'.format(service)), flags=1 << 0) LOG.info('Created augeas instance for parsing %s service.' % service) # Get config path from lens key = '/augeas/load/{}/incl'.format(service.capitalize()) LOG.info('augtool> get %s' % key) res = parser.get(key) LOG.info('result > %s' % res) assert res, '{} lens was not load properly.'.format(service.capitalize()) # Create sample config config_path = res[1:] if res.startswith('/') else res setattr(context, 'config_path', config_path) sample_config = os.path.join(getattr(context, 'AUGEAS_ROOT'), config_path) if not os.path.exists(os.path.dirname(sample_config)): os.makedirs(os.path.dirname(sample_config)) with open(sample_config, "w") as f: f.write(context.text) assert os.path.exists(sample_config) or not os.path.getsize(sample_config),\ "Can't create sample config: {}".format(sample_config) LOG.info('Config %s was successfully created' % sample_config) setattr(context, 'parser', parser) setattr(context, 'service', service)
class SysConfig(object): def __init__(self, system_ip=None, system_id=None, system_type=None): """ Initialize this object with non system related data, like the OSSIM administration IP address. """ self.__system_ip = system_ip if is_ipv4(system_ip) else None self.__system_id = system_id self.__system_type = system_type self.__augeas = Augeas() self.__pending = {} # System data self.__net_ifaces = {} self.__hosts_entries = {} # Initialize pure system data. self.__reload_config__() # # Public methods # def is_pending(self): """ Are there pending changes? """ return self.__pending != {} def get_pending(self): """ Get which changes are pending """ return self.__pending def get_pending_str(self): """ Same as get_pending(), but in human format. """ data = '' for key, value in self.__pending.iteritems(): data += '\n[%s]\n%s' % (key, value) return data def apply_changes(self): """ Apply pending changes and reload configuration. """ if not self.is_pending(): return AVConfigParserErrors.ALL_OK try: self.__augeas.save() except IOError, msg: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.CANNOT_SAVE_SYSCONFIG, str(msg)) self.__pending = {} self.__reload_config__() return AVConfigParserErrors.ALL_OK
def remove(path): ''' Get matches for path expression CLI Example: .. code-block:: bash salt '*' augeas.remove /files/etc/sysctl.conf/net.ipv4.conf.all.log_martians ''' aug = Augeas() ret = {'retval': False} try: count = aug.remove(path) aug.save() if count == -1: ret['error'] = 'Invalid node' else: ret['retval'] = True except (RuntimeError, IOError) as err: ret['error'] = str(err) ret['count'] = count return ret
def remove(path): """ Get matches for path expression CLI Example:: salt '*' augeas.remove /files/etc/sysctl.conf/net.ipv4.conf.all.log_martians """ from augeas import Augeas aug = Augeas() ret = {"retval": False} try: count = aug.remove(path) aug.save() if count == -1: ret["error"] = "Invalid node" else: ret["retval"] = True except (RuntimeError, IOError) as err: ret["error"] = str(err) ret["count"] = count return ret
def get(path, value=''): ''' Get a value for a specific augeas path CLI Example: .. code-block:: bash salt '*' augeas.get /files/etc/hosts/1/ ipaddr ''' aug = Augeas() ret = {} path = path.rstrip('/') if value: path += '/{0}'.format(value.strip('/')) try: _match = aug.match(path) except RuntimeError as err: return {'error': str(err)} if _match: ret[path] = aug.get(path) else: ret[path] = '' # node does not exist return ret
class SysConfig (object): def __init__ (self, system_ip = None, system_id = None, system_type = None): """ Initialize this object with non system related data, like the OSSIM administration IP address. """ self.__system_ip = system_ip if is_ipv4(system_ip) else None self.__system_id = system_id self.__system_type = system_type self.__augeas = Augeas() self.__pending = {} # System data self.__net_ifaces = {} self.__hosts_entries = {} # Initialize pure system data. self.__reload_config__ () # # Public methods # def is_pending (self): """ Are there pending changes? """ return self.__pending != {} def get_pending (self): """ Get which changes are pending """ return self.__pending def get_pending_str (self): """ Same as get_pending(), but in human format. """ data = '' for key, value in self.__pending.iteritems(): data += '\n[%s]\n%s' % (key, value) return data def apply_changes (self): """ Apply pending changes and reload configuration. """ if not self.is_pending(): return AVConfigParserErrors.ALL_OK try: self.__augeas.save() except IOError, msg: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.CANNOT_SAVE_SYSCONFIG, str(msg)) self.__pending = {} self.__reload_config__ () return AVConfigParserErrors.ALL_OK
def epel_repo(): """ Setup EPEL repository. """ # Check if epel is already installed and enabled augeas = Augeas(x) epel_enabled = augeas.find_values('/files/etc/yum.repos.d/epel.repo/epel/enabled') if len(epel_enabled) != 1 or epel_enabled[0] != '1': x("yum install -y epel-release") augeas.set_enhanced('/files/etc/yum.repos.d/epel.repo/epel/enabled', '1')
def setvalue(*args): ''' Set a value for a specific augeas path CLI Example:: salt '*' augeas.setvalue /files/etc/hosts/1/canonical localhost salt '*' augeas.setvalue /files/etc/hosts/01/ipaddr 192.168.1.1 \ /files/etc/hosts/01/canonical hostname salt '*' augeas.setvalue prefix=/files/etc/sudoers/ \ "/spec[user = '******']/user" "%wheel" \ "/spec[user = '******']/host_group/host" 'ALL' \ "/spec[user = '******']/host_group/command[1]" 'ALL' \ "/spec[user = '******']/host_group/command[1]/tag" 'PASSWD' \ "/spec[user = '******']/host_group/command[2]" '/usr/bin/apt-get' \ "/spec[user = '******']/host_group/command[2]/tag" NOPASSWD ''' from augeas import Augeas aug = Augeas() ret = {'retval': False} prefix = None tuples = filter(lambda x: not x.startswith('prefix='), args) prefix = filter(lambda x: x.startswith('prefix='), args) if prefix: prefix = prefix[0].split('=', 1)[1] if len(tuples) % 2 != 0: return ret # ensure we have multiple of twos tuple_iter = iter(tuples) for path, value in zip(tuple_iter, tuple_iter): target_path = path if prefix: target_path = "{0}/{1}".format(prefix.rstrip('/'), path.lstrip('/')) try: aug.set(target_path, str(value)) except ValueError as err: ret['error'] = "Multiple values: " + str(err) try: aug.save() ret['retval'] = True except IOError as err: ret['error'] = str(err) return ret
def get_configured_ifaces(): aug = Augeas(flags=Augeas.NO_MODL_AUTOLOAD) aug.add_transform('interfaces', '/etc/network/interfaces') aug.load() base = '/files/etc/network/interfaces' for m in aug.match('%s/iface' % base): yield aug.get(m) aug.close()
def epel_repo(): """ Setup EPEL repository. """ # Check if epel is already installed and enabled augeas = Augeas(x) epel_enabled = augeas.find_values( '/files/etc/yum.repos.d/epel.repo/epel/enabled') if len(epel_enabled) != 1 or epel_enabled[0] != '1': x("yum install -y epel-release") augeas.set_enhanced('/files/etc/yum.repos.d/epel.repo/epel/enabled', '1')
def set(self,entryPath,param='',pvalue='',hierarchy='/files'): """Set/change a value for a config. parameter in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') try: aug.set(path,pvalue) except Exception, e: return str(e) # Here is a little workaround for a bug in save for augeas. # In the future this won't be necessary anymore. try: aug.save() except: pass # End of workaround try: aug.save() except Exception, e: return str(e) try: pvalue=aug.get(path) #aug.close() except Exception, e: return str(e) return { 'path': entryPath, 'parameter': param, 'value': pvalue, 'hierarchy': hierarchy }
def _configure_keepalived(): """ * Keepalived needs the possibility to bind on non local adresses. * It will replace the variables in the config file with the hostname. * It is not environmental dependent and can be installed on any server. """ augeas = Augeas(x) augeas.set_enhanced("/files/etc/sysctl.conf/net.ipv4.ip_nonlocal_bind", "1") x("sysctl -p") x("mv {0}keepalived.conf {0}org.keepalived.conf".format(KA_CONF_DIR)) x("cp {0}/{1}.keepalived.conf {2}keepalived.conf".format(SYCO_PLUGIN_PATH, ka_env, KA_CONF_DIR)) scopen.scOpen(KA_CONF_DIR + "keepalived.conf").replace("${KA_SERVER_NAME_UP}", socket.gethostname().upper()) scopen.scOpen(KA_CONF_DIR + "keepalived.conf").replace("${KA_SERVER_NAME_DN}", socket.gethostname().lower()) _chkconfig("keepalived","on") _service("keepalived","restart")
def execute(*args, **kw): if conf.has_section('example.org'): primary_domain = conf.get('kolab', 'primary_domain') if not primary_domain == 'example.org': utils.multiline_message( _(""" Copying the configuration section for 'example.org' over to a section applicable to your domain '%s'. """) % (primary_domain)) conf.cfg_parser._sections[primary_domain] = \ conf.cfg_parser._sections['example.org'] conf.cfg_parser._sections.pop('example.org') fp = open(conf.cli_keywords.config_file, "w+") conf.cfg_parser.write(fp) fp.close() if os.path.isfile('/etc/default/kolab-server'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/kolab-server', 'START') if not myaugeas.get(setting) == 'yes': myaugeas.set(setting, 'yes') myaugeas.save() myaugeas.close() if os.path.isfile('/bin/systemctl'): if os.path.isfile('/etc/debian_version'): subprocess.call( ['/bin/systemctl', 'restart', 'kolab-server.service']) else: subprocess.call(['/bin/systemctl', 'restart', 'kolabd.service']) elif os.path.isfile('/sbin/service'): subprocess.call(['/sbin/service', 'kolabd', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service', 'kolab-server', 'restart']) else: log.error(_("Could not start the kolab server service.")) if os.path.isfile('/bin/systemctl'): if os.path.isfile('/etc/debian_version'): subprocess.call( ['/bin/systemctl', 'enable', 'kolab-server.service']) else: subprocess.call(['/bin/systemctl', 'enable', 'kolabd.service']) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['/sbin/chkconfig', 'kolabd', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'kolab-server', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "kolab server service."))
def ls(path): # pylint: disable-msg=C0103 ''' List the direct children of a node CLI Example:: salt '*' augeas.ls /files/etc/passwd ''' def _match(path): ''' Internal match function ''' try: matches = aug.match(path) except RuntimeError: return {} ret = {} for _ma in matches: ret[_ma] = aug.get(_ma) return ret aug = Augeas() path = path.rstrip('/') + '/' match_path = path + '*' matches = _match(match_path) ret = {} for key, value in matches.iteritems(): name = _lstrip_word(key, path) if _match(key + '/*'): ret[name + '/'] = value # has sub nodes, e.g. directory else: ret[name] = value return ret
def install_sssd(args): """ Install ldap client on current host and connect to networks ldap server. """ app.print_verbose("Install sssd script-version: %d" % SCRIPT_VERSION) version_obj = version.Version("InstallSssd", SCRIPT_VERSION) version_obj.check_executed() # Get all passwords from installation user at the start of the script. app.get_ldap_sssd_password() install_packages() installOpenLdap.setup_hosts() iptables.add_ldap_chain() iptables.save() ip = config.general.get_ldap_server_ip() general.wait_for_server_to_start(ip, "636") install_certs() # For some reason it needs to be executed twice. authconfig() authconfig() installOpenLdap.configure_client_cert_for_ldaptools() augeas = Augeas(x) create_sss_folders() configure_sssd(augeas) configure_sudo(augeas) version_obj.mark_executed()
def execute(*args, **kw): if conf.timezone == None: print >> sys.stderr, utils.multiline_message( _(""" Please supply the timezone PHP should be using. You have to use a Continent or Country / City locality name like 'Europe/Berlin', but not just 'CEST'. """)) conf.timezone = utils.ask_question(_("Timezone ID"), default="UTC") if not conf.php_ini_path == None: if not os.path.isfile(conf.php_ini_path): log.error( _("Cannot configure PHP through %r (No such file or directory)" ) % (conf.php_ini_path)) return php_ini = conf.php_ini_path else: # Search and destroy php_ini = "/etc/php.ini" if not os.path.isfile(php_ini): php_ini = "/etc/php5/apache2/php.ini" if not os.path.isfile(php_ini): log.error(_("Could not find PHP configuration file php.ini")) return myaugeas = Augeas() setting_base = '/files%s/' % (php_ini) setting = os.path.join(setting_base, 'Date', 'date.timezone') current_value = myaugeas.get(setting) if current_value == None: insert_paths = myaugeas.match('/files%s/Date/*' % (php_ini)) insert_path = insert_paths[(len(insert_paths) - 1)] myaugeas.insert(insert_path, 'date.timezone', False) log.debug(_("Setting key %r to %r") % ('Date/date.timezone', conf.timezone), level=8) myaugeas.set(setting, conf.timezone) myaugeas.save()
def rm(self, entryPath, param='', hierarchy='/files'): """Delete a parameter (and all its children) in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug = Augeas() except Exception, e: return str(e)
def set(self, entryPath, param='', pvalue='', hierarchy='/files'): """Set/change a value for a config. parameter in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug = Augeas() except Exception, e: return str(e)
def ls(self, entryPath, hierarchy='/files'): """List the direct children of an entry in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug = Augeas() except Exception, e: return str(e)
def printconf(self, entryPath, hierarchy='/files'): """Print all tree children nodes from the path provided, with the help of Augeas, a configuration API (cf http://augeas.net)""" path = hierarchy + entryPath try: from augeas import Augeas aug = Augeas() except Exception, e: return str(e)
def __init__(self, system_ip=None, system_id=None, system_type=None): """ Initialize this object with non system related data, like the OSSIM administration IP address. """ self.__system_ip = system_ip if is_ipv4(system_ip) else None self.__system_id = system_id self.__system_type = system_type self.__augeas = Augeas() self.__pending = {} # System data self.__net_ifaces = {} self.__hosts_entries = {} # Initialize pure system data. self.__reload_config__()
def execute(*args, **kw): if conf.timezone == None: print >> sys.stderr, utils.multiline_message( _(""" Please supply the timezone PHP should be using. You have to use a Continent or Country / City locality name like 'Europe/Berlin', but not just 'CEST'. """) ) conf.timezone = utils.ask_question( _("Timezone ID"), default="UTC" ) if not conf.php_ini_path == None: if not os.path.isfile(conf.php_ini_path): log.error(_("Cannot configure PHP through %r (No such file or directory)") % (conf.php_ini_path)) return php_ini = conf.php_ini_path else: # Search and destroy php_ini = "/etc/php.ini" if not os.path.isfile(php_ini): php_ini = "/etc/php5/apache2/php.ini" if not os.path.isfile(php_ini): log.error(_("Could not find PHP configuration file php.ini")) return myaugeas = Augeas() setting_base = '/files%s/' % (php_ini) setting = os.path.join(setting_base, 'Date', 'date.timezone') current_value = myaugeas.get(setting) if current_value == None: insert_paths = myaugeas.match('/files%s/Date/*' % (php_ini)) insert_path = insert_paths[(len(insert_paths)-1)] myaugeas.insert(insert_path, 'date.timezone', False) log.debug(_("Setting key %r to %r") % ('Date/date.timezone', conf.timezone), level=8) myaugeas.set(setting, conf.timezone) myaugeas.save()
def __init__(self, confpath, lens, root=None, loadpath=None, flags=Augeas.NO_MODL_AUTOLOAD | Augeas.NO_LOAD | Augeas.ENABLE_SPAN): """Parse configuration file using given lens. Params: confpath (str): Absolute path to the configuration file lens (str): Name of module containing Augeas lens root: passed down to original Augeas flags: passed down to original Augeas loadpath: passed down to original Augeas flags: passed down to original Augeas """ log.debug('loadpath: %s', loadpath) log.debug('confpath: %s', confpath) self._aug = Augeas(root=root, loadpath=loadpath, flags=flags) # /augeas/load/{lens} aug_load_path = join(AUGEAS_LOAD_PATH, lens) # /augeas/load/{lens}/lens = {lens}.lns self._aug.set(join(aug_load_path, 'lens'), '%s.lns' % lens) # /augeas/load/{lens}/incl[0] = {confpath} self._aug.set(join(aug_load_path, 'incl[0]'), confpath) self._aug.load() errors = self._aug.match(AUGEAS_ERROR_PATH) if errors: err_msg = '\n'.join( ["{}: {}".format(e, self._aug.get(e)) for e in errors]) raise RuntimeError(err_msg) path = join(AUGEAS_FILES_PATH, confpath) paths = self._aug.match(path) if len(paths) != 1: raise ValueError('path %s did not match exactly once' % path) self.tree = AugeasNode(self._aug, path) self._loaded = True
def _configure_keepalived(): """ * Keepalived needs the possibility to bind on non local adresses. * It will replace the variables in the config file with the hostname. * It is not environmental dependent and can be installed on any server. """ augeas = Augeas(x) augeas.set_enhanced("/files/etc/sysctl.conf/net.ipv4.ip_nonlocal_bind", "1") x("sysctl -p") x("mv {0}keepalived.conf {0}org.keepalived.conf".format(KA_CONF_DIR)) x("cp {0}/{1}.keepalived.conf {2}keepalived.conf".format( SYCO_PLUGIN_PATH, ka_env, KA_CONF_DIR)) scopen.scOpen(KA_CONF_DIR + "keepalived.conf").replace( "${KA_SERVER_NAME_UP}", socket.gethostname().upper()) scopen.scOpen(KA_CONF_DIR + "keepalived.conf").replace( "${KA_SERVER_NAME_DN}", socket.gethostname().lower()) _chkconfig("keepalived", "on") _service("keepalived", "restart")
def init_augeas() -> Augeas: """ Initialize the actual Augeas instance """ if not Augeas: # pragma: no cover raise errors.NoInstallationError("Problem in Augeas installation") return Augeas( # specify a directory to load our preferred lens from loadpath=constants.AUGEAS_LENS_DIR, # Do not save backup (we do it ourselves), do not load # anything by default flags=(Augeas.NONE | Augeas.NO_MODL_AUTOLOAD | Augeas.ENABLE_SPAN))
def rm(self,entryPath,param='',hierarchy='/files'): """Delete a parameter (and all its children) in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') try: result=aug.remove(path) #aug.close() except Exception, e: return str(e) # Here is a little workaround for a bug in save for augeas. # In the future this should not be necessary anymore. try: aug.save() except: pass # End of workaround try: aug.save() except Exception, e: return str(e) if result == -1: msg = 'Invalid node' else: msg = repr(result)+' node(s) removed.' return msg
def match(self,entryPath,param='',pvalue='',hierarchy='/files'): """Match a value for a config. parameter in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') childpath=(hierarchy+entryPath.rstrip('/')+'/*/'+param).rstrip('/') if pvalue: try: matchlist = [ ospath.dirname(lstripstr(item,'/files')) for item in aug.match(path) + aug.match(childpath) if ( aug.get(item) == pvalue ) ] #aug.close() except Exception, e: return str(e) else: try: matchlist = [ ospath.dirname(lstripstr(item,'/files')) for item in aug.match(path) + aug.match(childpath) ] #aug.close() except Exception, e: return str(e) return matchlist
def setUp(self): self.tmp = tempfile.mkdtemp() self.root = "%s/root" % self.tmp shutil.copytree("%s/fakeroot" % os.path.dirname(__file__), self.root) self.aug = Augeas(root=self.root, flags=Augeas.NO_MODL_AUTOLOAD) self.aug.add_transform("Nsswitch.lns", "/etc/nsswitch.conf") self.aug.load() class FakeParent: def setpath(self): return "/files/etc/nsswitch.conf" self.parent = FakeParent()
def tree(path): ''' Returns recursively the complete tree of a node CLI Example:: salt '*' augeas.tree /files/etc/ ''' aug = Augeas() path = path.rstrip('/') + '/' match_path = path return dict([i for i in _recurmatch(match_path, aug)])
def _augeas_init(): if not _directories_inited: init_directories() global augeas augeas = Augeas(loadpath=get_config_path(), flags=Augeas.SAVE_BACKUP | Augeas.NO_MODL_AUTOLOAD) augeas.set("/augeas/load/Agocontrol/lens", "agocontrol.lns"); augeas.set("/augeas/load/Agocontrol/incl[1]", get_config_path("conf.d") + "/*.conf"); augeas.load()
def set_api_timeouts(self, timeout): # Determine the file to change if self.https: config_file = self.abiquo_ssl_conf else: config_file = self.abiquo_conf logging.info("Setting Proxy timeouts in %s" % config_file) # Set timeout using Augeas a = Augeas() for loc in a.match("/files%s/VirtualHost/*[arg='/api']" % config_file): proxy_pass = a.match("%s/*[self::directive='ProxyPass']" % loc) if len(proxy_pass) == 1: # Proxy timeout already exists logging.info("ProxyPass found") arg1 = a.get("%s/arg" % proxy_pass[0]) arg2 = "timeout=%s" % timeout a.set("%s/arg[1]" % proxy_pass[0], arg1) a.set("%s/arg[2]" % proxy_pass[0], arg2) a.save() a.close()
def ls(self,entryPath,hierarchy='/files'): """List the direct children of an entry in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) path=hierarchy+entryPath.rstrip('/')+'/*' # We can't use a dict here because the same key can appear many times. nodes=[] try: for match in aug.match(path): pvalue=aug.get(match) if not pvalue: pvalue='(none)' nodes.append([ospath.basename(match),pvalue]) except Exception, e: return str(e) #try: # aug.close() #except Exception, e: return str(e) return { 'path': entryPath, 'nodes': nodes, 'hierarchy': hierarchy }
def __init__(self, path="/etc/lvm/lvm.conf"): self.path = path # Augeas loads by default tons of unneeded lenses and configuration # files. On my test host, it fails to load, trying to read my 500 MiB # /etc/lvm/archive/. # # These are the standard LVM lens includes: # /augeas/load/LVM/incl[1] /etc/lvm/lvm.conf # /augeas/load/LVM/incl[2] /etc/lvm/backup/* # /augeas/load/LVM/incl[3] /etc/lvm/archive/*.vg # # We need only the first entry to work with lvm.conf. Using customized # load setup, as explained in # https://github.com/hercules-team/augeas/wiki/Loading-specific-files # # Removing the archive and backup entries, we can load augeas in 0.7 # seconds on my test vm. Removing all other lenses shorten the time to # 0.04 seconds. log.debug("Loading LVM configuration from %r", path) self.aug = Augeas(flags=Augeas.NO_MODL_AUTOLOAD | Augeas.SAVE_BACKUP) self.aug.add_transform("lvm.lns", [path]) self.aug.load()
def setvalue(name, expressions): ret = {"name": name, "result": True, "changes": {}, "comment": "No changes made"} from augeas import Augeas if len(expressions) < 1: ret["comment"] = "No expressions given" ret["result"] = False return ret if __opts__["test"]: aug = Augeas(flags=Augeas.SAVE_NEWFILE) sfn = name dfn = "%s.augnew" % name else: aug = Augeas(flags=Augeas.SAVE_BACKUP) sfn = "%s.augsave" % name dfn = name if not os.path.isfile(name): ret["comment"] = "Unable to find file '%s'" % name ret["result"] = False return ret for (subpath, value) in expressions: try: path = "/files%s/%s" % (name, subpath) aug.set(path, value) except ValueError as e: ret["comment"] = '%s for\n"%s" = "%s"' % (e, path, value) ret["result"] = False return ret except TypeError as e: ret["comment"] = ( "Error setting values:\n" "%s\n" "Expression was '%s' '%s'\n" "Try quoting the value" % (e, path, value) ) ret["result"] = False return ret except e: ret["comment"] = "Unknown error:\n%s" % e ret["result"] = False return ret try: aug.save() except IOError as e: ret["comment"] = str(e) ret["result"] = False return ret ret.update(_resolve_changes(sfn, dfn)) return ret
def setup_clam_and_freshclam(): # # Setup clamav and freshclam # app.print_verbose("Setup clamav and freshclam") app.print_verbose(" Setup config files.") x("cp /usr/local/etc/clamd.conf.sample /usr/local/etc/clamd.conf") clamd = scOpen("/usr/local/etc/clamd.conf") clamd.replace("^[#]\?Example.*", "#Example") clamd.replace("^[#]\?LogFileMaxSize.*", "LogFileMaxSize 100M") clamd.replace("^[#]\?LogFile.*", "LogFile /var/log/clamav/clamd.log") clamd.replace("^[#]\?LogTime.*", "LogTime yes") clamd.replace("^[#]\?LogSyslog.*", "LogSyslog yes") clamd.replace("^[#]\?TCPSocket.*", "TCPSocket 3310") clamd.replace("^[#]\?TCPAddr.*", "TCPAddr 127.0.0.1") clamd.replace("^[#]\?ExcludePath.*/proc.*", "ExcludePath ^/proc") clamd.replace("^[#]\?ExcludePath.*/sys.*", "ExcludePath ^/sys") clamd.replace("^[#]\?User.*", "User clamav") clamd.replace("^[#]\?LocalSocket.*", "LocalSocket /var/run/clamav/clamd.socket") clamd.replace("^[#]\?PidFile.*", "PidFile /var/run/clamav/clamd.pid") clamd.replace("^[#]\?DatabaseDirectory.*", "DatabaseDirectory /var/lib/clamav") x("cp /usr/local/etc/freshclam.conf.sample /usr/local/etc/freshclam.conf") freshclam = scOpen("/usr/local/etc/freshclam.conf") freshclam.replace("^[#]\?Example.*", "#Example") freshclam.replace("^[#]\?LogFileMaxSize.*", "LogFileMaxSize 100M") freshclam.replace("^[#]\?LogTime.*", "LogTime yes") freshclam.replace("^[#]\?LogSyslog.*", "LogSyslog yes") freshclam.replace("^[#]\?DatabaseOwner.*", "DatabaseOwner clamav") freshclam.replace("^[#]\?PidFile.*", "PidFile /var/run/clamav/freshclam.pid") freshclam.replace("^[#]\?DatabaseMirror.*", "DatabaseMirror db.northeu.clamav.net") freshclam.replace("^[#]\?UpdateLogFile.*", "UpdateLogFile /var/log/clamav/freshclam.log") freshclam.replace("^[#]\?DatabaseDirectory.*", "DatabaseDirectory /var/lib/clamav") #TODO: Change replace statements above to augeas since that tends to be more stable. app.print_verbose(" Install augeas and add clam lens that is not available on CentOS 6") x("yum install -y augeas") x("cp %s/augeas/lenses/clamav.aug /usr/share/augeas/lenses/dist/" % app.SYCO_VAR_PATH) #Help augeas find freshclam.conf if x("readlink /etc/freshclam.conf").find("/usr/local/etc/freshclam.conf") == -1: x("rm -f /etc/freshclam.conf") x("ln -s /usr/local/etc/freshclam.conf /etc/") #Initialize augeas augeas = Augeas(x) if config.general.get_proxy_host() and config.general.get_proxy_port(): app.print_verbose(" Configure proxy for freshclam") augeas.set_enhanced("/files/etc/freshclam.conf/HTTPProxyPort", "%s" % config.general.get_proxy_port()) augeas.set_enhanced("/files/etc/freshclam.conf/HTTPProxyServer", "%s" % config.general.get_proxy_host())
def install_syco(args): """ Install/configure this script on the current computer. """ app.print_verbose("Install syco version: %d" % SCRIPT_VERSION) version_obj = version.Version("InstallSYCO", SCRIPT_VERSION) version_obj.check_executed() # Override base repo to one that works x("cat %syum/CentOS-Base.repo > /etc/yum.repos.d/CentOS-Base.repo" % app.SYCO_VAR_PATH) # Run all yum updates through proxy if available proxy_host = config.general.get_proxy_host() proxy_port = config.general.get_proxy_port() if proxy_host and proxy_port: x('echo proxy=%s >> /etc/yum.conf' % "http://%s:%s" % (proxy_host, proxy_port)) app.print_verbose("Install required packages for syco") install_packages("augeas") app.print_verbose("Create symlink /sbin/syco") set_syco_permissions() if not os.path.exists('/sbin/syco'): os.symlink('%sbin/syco.py' % SYCO_PATH, '/sbin/syco') # Use augeas to set max kernels to 2 since more won't fit on /boot from augeas import Augeas augeas = Augeas(x) augeas.set_enhanced("/files/etc/yum.conf/main/installonly_limit", "2") # Set Swappiness to 0 on all hosts to avoid excessive swapping augeas.set_enhanced("/files/etc/sysctl.conf/vm.swappiness", "0") if proxy_host and proxy_port: # Set proxy again with augeas to ensure there are no duplicates/inconsistencies augeas.set_enhanced("/files/etc/yum.conf/main/proxy", "http://%s:%s" % (proxy_host, proxy_port)) version_obj.mark_executed()
def __init__ (self, system_ip = None, system_id = None, system_type = None): """ Initialize this object with non system related data, like the OSSIM administration IP address. """ self.__system_ip = system_ip if is_ipv4(system_ip) else None self.__system_id = system_id self.__system_type = system_type self.__augeas = Augeas() self.__pending = {} # System data self.__net_ifaces = {} self.__hosts_entries = {} # Initialize pure system data. self.__reload_config__ ()
def get_augeas(self, entry): """ Get an augeas object for the given entry. """ if entry.get("name") not in self._augeas: aug = Augeas() if entry.get("lens"): self.logger.debug("Augeas: Adding %s to include path for %s" % (entry.get("name"), entry.get("lens"))) incl = "/augeas/load/%s/incl" % entry.get("lens") ilen = len(aug.match(incl)) if ilen == 0: self.logger.error("Augeas: Lens %s does not exist" % entry.get("lens")) else: aug.set("%s[%s]" % (incl, ilen + 1), entry.get("name")) aug.load() self._augeas[entry.get("name")] = aug return self._augeas[entry.get("name")]
def __init__(self): self.aug = Augeas() self.cur_file = "" self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title("Augeas viewer") self.window.set_size_request(500, 400) self.window.connect("delete_event", self.delete_event) self.tree_store = gtk.TreeStore(str, str) self.populate_tree_store('/', None) self.treeview = gtk.TreeView(self.tree_store) for (i, columnName) in enumerate(['Path', 'Value']): column = gtk.TreeViewColumn(columnName) self.treeview.append_column(column) cr = gtk.CellRendererText() column.pack_start(cr, True) column.add_attribute(cr, 'text', i) column.set_sort_column_id(i) self.treeview.set_search_column(0) self.textview = gtk.TextView() self.setup_tags(None) hbox = gtk.HBox() add_with_scrolling(hbox, self.treeview) add_with_scrolling(hbox, self.textview) self.window.add(hbox) self.treeview.get_selection().connect('changed', self.on_selection_changed, self) self.window.show_all()
def install_syco(args): """ Install/configure this script on the current computer. """ app.print_verbose("Install syco version: %d" % SCRIPT_VERSION) version_obj = version.Version("InstallSYCO", SCRIPT_VERSION) version_obj.check_executed() # Override base repo to one that works x("cat %syum/CentOS-Base.repo > /etc/yum.repos.d/CentOS-Base.repo" % app.SYCO_VAR_PATH) # Run all yum updates through proxy if available proxy_host = config.general.get_proxy_host() proxy_port = config.general.get_proxy_port() if proxy_host and proxy_port: x('echo proxy=%s >> /etc/yum.conf' % "http://%s:%s" % (proxy_host,proxy_port)) app.print_verbose("Install required packages for syco") install_packages("augeas") app.print_verbose("Create symlink /sbin/syco") set_syco_permissions() if not os.path.exists('/sbin/syco'): os.symlink('%sbin/syco.py' % SYCO_PATH, '/sbin/syco') # Use augeas to set max kernels to 2 since more won't fit on /boot from augeas import Augeas augeas = Augeas(x) augeas.set_enhanced("/files/etc/yum.conf/main/installonly_limit", "2") # Set Swappiness to 0 on all hosts to avoid excessive swapping augeas.set_enhanced("/files/etc/sysctl.conf/vm.swappiness", "0") if proxy_host and proxy_port: # Set proxy again with augeas to ensure there are no duplicates/inconsistencies augeas.set_enhanced("/files/etc/yum.conf/main/proxy", "http://%s:%s" % (proxy_host,proxy_port)) version_obj.mark_executed()
def remove(name, values): ret = {"name": name, "result": True, "changes": {}, "comment": ""} from augeas import Augeas if len(values) < 1: ret["comment"] = "No values given" ret["result"] = False return ret if __opts__["test"]: aug = Augeas(flags=Augeas.SAVE_NEWFILE) sfn = name dfn = "%s.augnew" % name else: aug = Augeas(flags=Augeas.SAVE_BACKUP) sfn = "%s.augsave" % name dfn = name if not os.path.isfile(name): ret["comment"] = "Unable to find file '%s'" % name ret["result"] = False return ret for value in values: try: path = "/files%s/%s" % (name, value) aug.remove(path) except TypeError as e: ret["comment"] = "Error removing, wrong type\n" "Expression was '%s'" % path ret["result"] = False return ret try: aug.save() except IOError as e: ret["comment"] = str(e) ret["result"] = False return ret ret.update(_resolve_changes(sfn, dfn)) return ret
class AugeasWrapper(object): """python-augeas higher-level wrapper. Load single augeas lens and configuration file. Exposes configuration file as AugeasNode object with dict-like interface. AugeasWrapper can be used in with statement in the same way as file does. """ def __init__(self, confpath, lens, root=None, loadpath=None, flags=Augeas.NO_MODL_AUTOLOAD | Augeas.NO_LOAD | Augeas.ENABLE_SPAN): """Parse configuration file using given lens. Params: confpath (str): Absolute path to the configuration file lens (str): Name of module containing Augeas lens root: passed down to original Augeas flags: passed down to original Augeas loadpath: passed down to original Augeas flags: passed down to original Augeas """ log.debug('loadpath: %s', loadpath) log.debug('confpath: %s', confpath) self._aug = Augeas(root=root, loadpath=loadpath, flags=flags) # /augeas/load/{lens} aug_load_path = join(AUGEAS_LOAD_PATH, lens) # /augeas/load/{lens}/lens = {lens}.lns self._aug.set(join(aug_load_path, 'lens'), '%s.lns' % lens) # /augeas/load/{lens}/incl[0] = {confpath} self._aug.set(join(aug_load_path, 'incl[0]'), confpath) self._aug.load() errors = self._aug.match(AUGEAS_ERROR_PATH) if errors: err_msg = '\n'.join( ["{}: {}".format(e, self._aug.get(e)) for e in errors]) raise RuntimeError(err_msg) path = join(AUGEAS_FILES_PATH, confpath) paths = self._aug.match(path) if len(paths) != 1: raise ValueError('path %s did not match exactly once' % path) self.tree = AugeasNode(self._aug, path) self._loaded = True def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.save() self.close() def save(self): """Save Augeas tree to its original file.""" assert self._loaded try: self._aug.save() except IOError as exc: log.exception(exc) for err_path in self._aug.match('//error'): log.error('%s: %s', err_path, self._aug.get(os.path.join(err_path, 'message'))) raise def close(self): """ close Augeas library After calling close() the object must not be used anymore. """ assert self._loaded self._aug.close() del self._aug self._loaded = False def match(self, path): """Yield AugeasNodes matching given expression.""" assert self._loaded assert path log.debug('tree match %s', path) for matched_path in self._aug.match(path): yield AugeasNode(self._aug, matched_path)
def configure_chrony(ntp_servers, ntp_pool=None, fstore=None, sysstore=None, debug=False): """ This method only configures chrony client with ntp_servers or ntp_pool """ module = "chrony" if sysstore: sysstore.backup_state(module, "enabled", services.knownservices.chronyd.is_enabled()) aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD, loadpath=paths.USR_SHARE_IPA_DIR) try: logger.debug("Configuring chrony") chrony_conf = os.path.abspath(paths.CHRONY_CONF) aug.transform(module, chrony_conf) # loads chrony lens file aug.load() # loads augeas tree # augeas needs to prepend path with '/files' path = '/files{path}'.format(path=chrony_conf) # remove possible conflicting configuration of servers aug.remove('{}/server'.format(path)) aug.remove('{}/pool'.format(path)) aug.remove('{}/peer'.format(path)) if ntp_pool: logger.debug("Setting server pool:") logger.debug("'%s'", ntp_pool) aug.set('{}/pool[last()+1]'.format(path), ntp_pool) aug.set('{}/pool[last()]/iburst'.format(path), None) if ntp_servers: logger.debug("Setting time servers:") for server in ntp_servers: aug.set('{}/server[last()+1]'.format(path), server) aug.set('{}/server[last()]/iburst'.format(path), None) logger.debug("'%s'", server) # backup oginal conf file logger.debug("Backing up '%s'", chrony_conf) __backup_config(chrony_conf, fstore) logger.debug("Writing configuration to '%s'", chrony_conf) aug.save() logger.info('Configuration of chrony was changed by installer.') configured = True except IOError: logger.error("Augeas failed to configure file %s", chrony_conf) configured = False except RuntimeError as e: logger.error("Configuration failed with: %s", e) configured = False finally: aug.close() tasks.restore_context(chrony_conf) return configured
def __disable_mod_ssl_ocsp(self): aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') aug.set('/augeas/load/Httpd/incl', paths.HTTPD_SSL_CONF) aug.load() path = '/files{}/VirtualHost'.format(paths.HTTPD_SSL_CONF) ocsp_path = '{}/directive[.="{}"]'.format(path, OCSP_DIRECTIVE) ocsp_arg = '{}/arg'.format(ocsp_path) ocsp_comment = '{}/#comment[.="{}"]'.format(path, OCSP_DIRECTIVE) ocsp_dir = aug.get(ocsp_path) # there is SSLOCSPEnable directive in nss.conf file, comment it # otherwise just do nothing if ocsp_dir is not None: ocsp_state = aug.get(ocsp_arg) aug.remove(ocsp_arg) aug.rename(ocsp_path, '#comment') aug.set(ocsp_comment, '{} {}'.format(OCSP_DIRECTIVE, ocsp_state)) aug.save()
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. from ovirt.node import base from ovirt.node.utils.fs import Config from augeas import Augeas import os aug_unwrapped = Augeas() aug_unwrapped.set("/augeas/save/copy_if_rename_fails", "") class ConfigMigrationRunner(base.Base): def run_if_necessary(self): """Migrate the configs if needed """ migration_func = self._determine_migration_func() if migration_func: self._run(migration_func) else: self.logger.debug("No config migration needed") def _determine_migration_func(self):