%PDF- %PDF-
Direktori : /proc/self/root/usr/lib/python2.7/site-packages/salt/modules/ |
Current File : //proc/self/root/usr/lib/python2.7/site-packages/salt/modules/apache.py |
# -*- coding: utf-8 -*- ''' Support for Apache .. note:: The functions in here are generic functions designed to work with all implementations of Apache. Debian-specific functions have been moved into deb_apache.py, but will still load under the ``apache`` namespace when a Debian-based system is detected. ''' # Import python libs from __future__ import absolute_import, generators, print_function, with_statement, unicode_literals import re import logging # Import 3rd-party libs # pylint: disable=import-error,no-name-in-module from salt.ext import six from salt.ext.six.moves import cStringIO from salt.ext.six.moves.urllib.error import URLError from salt.ext.six.moves.urllib.request import ( HTTPBasicAuthHandler as _HTTPBasicAuthHandler, HTTPDigestAuthHandler as _HTTPDigestAuthHandler, urlopen as _urlopen, build_opener as _build_opener, install_opener as _install_opener ) # pylint: enable=import-error,no-name-in-module # Import salt libs import salt.utils.data import salt.utils.files import salt.utils.path import salt.utils.stringutils from salt.exceptions import SaltException log = logging.getLogger(__name__) def __virtual__(): ''' Only load the module if apache is installed ''' cmd = _detect_os() if salt.utils.path.which(cmd): return 'apache' return (False, 'The apache execution module cannot be loaded: apache is not installed.') def _detect_os(): ''' Apache commands and paths differ depending on packaging ''' # TODO: Add pillar support for the apachectl location os_family = __grains__['os_family'] if os_family == 'RedHat': return 'apachectl' elif os_family == 'Debian' or os_family == 'Suse': return 'apache2ctl' else: return 'apachectl' def version(): ''' Return server version (``apachectl -v``) CLI Example: .. code-block:: bash salt '*' apache.version ''' cmd = '{0} -v'.format(_detect_os()) out = __salt__['cmd.run'](cmd).splitlines() ret = out[0].split(': ') return ret[1] def fullversion(): ''' Return server version (``apachectl -V``) CLI Example: .. code-block:: bash salt '*' apache.fullversion ''' cmd = '{0} -V'.format(_detect_os()) ret = {} ret['compiled_with'] = [] out = __salt__['cmd.run'](cmd).splitlines() # Example # -D APR_HAS_MMAP define_re = re.compile(r'^\s+-D\s+') for line in out: if ': ' in line: comps = line.split(': ') if not comps: continue ret[comps[0].strip().lower().replace(' ', '_')] = comps[1].strip() elif ' -D' in line: cwith = define_re.sub('', line) ret['compiled_with'].append(cwith) return ret def modules(): ''' Return list of static and shared modules (``apachectl -M``) CLI Example: .. code-block:: bash salt '*' apache.modules ''' cmd = '{0} -M'.format(_detect_os()) ret = {} ret['static'] = [] ret['shared'] = [] out = __salt__['cmd.run'](cmd).splitlines() for line in out: comps = line.split() if not comps: continue if '(static)' in line: ret['static'].append(comps[0]) if '(shared)' in line: ret['shared'].append(comps[0]) return ret def servermods(): ''' Return list of modules compiled into the server (``apachectl -l``) CLI Example: .. code-block:: bash salt '*' apache.servermods ''' cmd = '{0} -l'.format(_detect_os()) ret = [] out = __salt__['cmd.run'](cmd).splitlines() for line in out: if not line: continue if '.c' in line: ret.append(line.strip()) return ret def directives(): ''' Return list of directives together with expected arguments and places where the directive is valid (``apachectl -L``) CLI Example: .. code-block:: bash salt '*' apache.directives ''' cmd = '{0} -L'.format(_detect_os()) ret = {} out = __salt__['cmd.run'](cmd) out = out.replace('\n\t', '\t') for line in out.splitlines(): if not line: continue comps = line.split('\t') desc = '\n'.join(comps[1:]) ret[comps[0]] = desc return ret def vhosts(): ''' Show the settings as parsed from the config file (currently only shows the virtualhost settings) (``apachectl -S``). Because each additional virtual host adds to the execution time, this command may require a long timeout be specified by using ``-t 10``. CLI Example: .. code-block:: bash salt -t 10 '*' apache.vhosts ''' cmd = '{0} -S'.format(_detect_os()) ret = {} namevhost = '' out = __salt__['cmd.run'](cmd) for line in out.splitlines(): if not line: continue comps = line.split() if 'is a NameVirtualHost' in line: namevhost = comps[0] ret[namevhost] = {} else: if comps[0] == 'default': ret[namevhost]['default'] = {} ret[namevhost]['default']['vhost'] = comps[2] ret[namevhost]['default']['conf'] = re.sub( r'\(|\)', '', comps[3] ) if comps[0] == 'port': ret[namevhost][comps[3]] = {} ret[namevhost][comps[3]]['vhost'] = comps[3] ret[namevhost][comps[3]]['conf'] = re.sub( r'\(|\)', '', comps[4] ) ret[namevhost][comps[3]]['port'] = comps[1] return ret def signal(signal=None): ''' Signals httpd to start, restart, or stop. CLI Example: .. code-block:: bash salt '*' apache.signal restart ''' no_extra_args = ('configtest', 'status', 'fullstatus') valid_signals = ('start', 'stop', 'restart', 'graceful', 'graceful-stop') if signal not in valid_signals and signal not in no_extra_args: return # Make sure you use the right arguments if signal in valid_signals: arguments = ' -k {0}'.format(signal) else: arguments = ' {0}'.format(signal) cmd = _detect_os() + arguments out = __salt__['cmd.run_all'](cmd) # A non-zero return code means fail if out['retcode'] and out['stderr']: ret = out['stderr'].strip() # 'apachectl configtest' returns 'Syntax OK' to stderr elif out['stderr']: ret = out['stderr'].strip() elif out['stdout']: ret = out['stdout'].strip() # No output for something like: apachectl graceful else: ret = 'Command: "{0}" completed successfully!'.format(cmd) return ret def useradd(pwfile, user, password, opts=''): ''' Add HTTP user using the ``htpasswd`` command. If the ``htpasswd`` file does not exist, it will be created. Valid options that can be passed are: .. code-block:: text n Don't update file; display results on stdout. m Force MD5 hashing of the password (default). d Force CRYPT(3) hashing of the password. p Do not hash the password (plaintext). s Force SHA1 hashing of the password. CLI Examples: .. code-block:: bash salt '*' apache.useradd /etc/httpd/htpasswd larry badpassword salt '*' apache.useradd /etc/httpd/htpasswd larry badpass opts=ns ''' return __salt__['webutil.useradd'](pwfile, user, password, opts) def userdel(pwfile, user): ''' Delete HTTP user from the specified ``htpasswd`` file. CLI Example: .. code-block:: bash salt '*' apache.userdel /etc/httpd/htpasswd larry ''' return __salt__['webutil.userdel'](pwfile, user) def server_status(profile='default'): ''' Get Information from the Apache server-status handler .. note:: The server-status handler is disabled by default. In order for this function to work it needs to be enabled. See http://httpd.apache.org/docs/2.2/mod/mod_status.html The following configuration needs to exists in pillar/grains. Each entry nested in ``apache.server-status`` is a profile of a vhost/server. This would give support for multiple apache servers/vhosts. .. code-block:: yaml apache.server-status: default: url: http://localhost/server-status user: someuser pass: password realm: 'authentication realm for digest passwords' timeout: 5 CLI Examples: .. code-block:: bash salt '*' apache.server_status salt '*' apache.server_status other-profile ''' ret = { 'Scoreboard': { '_': 0, 'S': 0, 'R': 0, 'W': 0, 'K': 0, 'D': 0, 'C': 0, 'L': 0, 'G': 0, 'I': 0, '.': 0, }, } # Get configuration from pillar url = __salt__['config.get']( 'apache.server-status:{0}:url'.format(profile), 'http://localhost/server-status' ) user = __salt__['config.get']( 'apache.server-status:{0}:user'.format(profile), '' ) passwd = __salt__['config.get']( 'apache.server-status:{0}:pass'.format(profile), '' ) realm = __salt__['config.get']( 'apache.server-status:{0}:realm'.format(profile), '' ) timeout = __salt__['config.get']( 'apache.server-status:{0}:timeout'.format(profile), 5 ) # create authentication handler if configuration exists if user and passwd: basic = _HTTPBasicAuthHandler() basic.add_password(realm=realm, uri=url, user=user, passwd=passwd) digest = _HTTPDigestAuthHandler() digest.add_password(realm=realm, uri=url, user=user, passwd=passwd) _install_opener(_build_opener(basic, digest)) # get http data url += '?auto' try: response = _urlopen(url, timeout=timeout).read().splitlines() except URLError: return 'error' # parse the data for line in response: splt = line.split(':', 1) splt[0] = splt[0].strip() splt[1] = splt[1].strip() if splt[0] == 'Scoreboard': for c in splt[1]: ret['Scoreboard'][c] += 1 else: if splt[1].isdigit(): ret[splt[0]] = int(splt[1]) else: ret[splt[0]] = float(splt[1]) # return the good stuff return ret def _parse_config(conf, slot=None): ''' Recursively goes through config structure and builds final Apache configuration :param conf: defined config structure :param slot: name of section container if needed ''' ret = cStringIO() if isinstance(conf, six.string_types): if slot: print('{0} {1}'.format(slot, conf), file=ret, end='') else: print('{0}'.format(conf), file=ret, end='') elif isinstance(conf, list): is_section = False for item in conf: if 'this' in item: is_section = True slot_this = six.text_type(item['this']) if is_section: print('<{0} {1}>'.format(slot, slot_this), file=ret) for item in conf: for key, val in item.items(): if key != 'this': print(_parse_config(val, six.text_type(key)), file=ret) print('</{0}>'.format(slot), file=ret) else: for value in conf: print(_parse_config(value, six.text_type(slot)), file=ret) elif isinstance(conf, dict): try: print('<{0} {1}>'.format(slot, conf['this']), file=ret) except KeyError: raise SaltException('Apache section container "<{0}>" expects attribute. ' 'Specify it using key "this".'.format(slot)) for key, value in six.iteritems(conf): if key != 'this': if isinstance(value, six.string_types): print('{0} {1}'.format(key, value), file=ret) elif isinstance(value, list): print(_parse_config(value, key), file=ret) elif isinstance(value, dict): print(_parse_config(value, key), file=ret) print('</{0}>'.format(slot), file=ret) ret.seek(0) return ret.read() def config(name, config, edit=True): ''' Create VirtualHost configuration files name File for the virtual host config VirtualHost configurations .. note:: This function is not meant to be used from the command line. Config is meant to be an ordered dict of all of the apache configs. CLI Example: .. code-block:: bash salt '*' apache.config /etc/httpd/conf.d/ports.conf config="[{'Listen': '22'}]" ''' configs = [] for entry in config: key = next(six.iterkeys(entry)) configs.append(_parse_config(entry[key], key)) # Python auto-correct line endings configstext = '\n'.join(salt.utils.data.decode(configs)) if edit: with salt.utils.files.fopen(name, 'w') as configfile: configfile.write('# This file is managed by Salt.\n') configfile.write(salt.utils.stringutils.to_str(configstext)) return configstext