16 ene 2012

httpd.conf VirtualHost Splitter

Sin duda, ser ordenados nos lleva a tener una mejor administración de los
recursos. Y más, si estamos hablando de una gran infraestructura de servidores Apache que alojan cientos de hosts virtuales.

Por esta razón he creado un script python el cual ayudará en ésta tarea. La filosofía fue la siguiente:


  1. Generar un archivo de configuración por cada VirtualHost, usando la directiva de Apache "ServerName" por ejemplo: "ServerName".conf 
  2. Guardar cada archivo creado en en nuevo directorio: /etc/httpd/vhosts/ 
  3. Incluir el nuevo directorio en la configuración principal de Apache: Include vhost/*.conf
  4. Finalmente, comentar todos los VirtualHosts del archivo de configuración principal. 
  5. Refrescar la configuración de Apache.
El script ejecuta algunos comandos de sistema, el primero respalda el
httpd.conf original por cualquiero cosa (no está de más). Y otros comandos cambian permisos de carpetas y archivos para poder ser usados con otros propósitos (Una interfaz Web)

Bien, aquí les dejo el script, espero sea de su utilidad.
#!/usr/bin/python
# AUTHORS:     ANGEL CABRERA, ALEJANDRO GUADARRAMA
# DATE:      11/01/2012
# DESCR:      HTTPD.CONF SPLITTER


import re, sys, os

vhost_dir = "/etc/httpd/vhost/"
os.system('cp -rp %s %s.bak' % (sys.argv[1], sys.argv[1]))
print "\nRespaldando configuracion actual..."

if os.path.exists(vhost_dir):
    print "\nYa existe el directorio ", vhost_dir, "\n"
else:
    print "\nCreando el directorio ", vhost_dir, "\n"
    os.makedirs(vhost_dir)
    os.chmod(vhost_dir,0775)

if len(sys.argv) == 1:
  print "Uso: split.py <httpd.conf>"
  sys.exit(1)

input = open(sys.argv[1], "rb")
p_include = re.compile(r"[I,i]nclude /etc/httpd/conf.d/vhosts/\*.conf")
p_comment = re.compile(r"[\s\t]*#.*")
p_begin = re.compile(r"<VirtualHost[^>]+>")
p_end = re.compile(r"</VirtualHost>")
p_server = re.compile(r"[S,s]erver[N,n]ame[\s\t]*(.*)")
file_name = "default"
found = False
commented = False
servers = {}
new_lines = []
archivo_comentado = []
n_total = 0
n_commented = 0
num_servers = 0
n_include = []
total_lineas = 0
iniciando = True
primer_host = 0

for line in input:
  total_lineas += 1
  if not found:
    i = p_include.search(line)
    if i:
      n_include.append(line)
    m = p_begin.search(line)
    if m:
      found = True
      if iniciando:
        primer_host = total_lineas
    iniciando  = False         
      file_name = "default"
      new_lines.append(line)
      m = p_comment.search(line)
      commented = False
      archivo_comentado.append("#"+line)
      if m:
        commented = True
  else:
    archivo_comentado.append("#"+line)
    new_lines.append(line)
    m = p_server.search(line)
    if m:
      file_name = m.group(1).strip()
    m = p_end.search(line)
    if m:
      found = False
      if num_servers == 0 and not commented:
    prefijo = "1_"
      else:
    prefijo = ""
      nombre_arch = vhost_dir+prefijo+file_name+".conf"
      if file_name in servers:
        servers[file_name] += 1
        file_name += "-%d" % servers[file_name]
      else:
        servers[file_name] = 0
      if commented:
        n_commented += 1
        print "Omitiendo virtual host... %s" % nombre_arch +"\n"
      else:
    num_servers += 1
        print "Creando virtual host... %s" % nombre_arch +"\n"
        output = open(nombre_arch, "wb")
        output.writelines(new_lines)
        output.close()
    os.chmod(nombre_arch,0664)
        new_lines = []
      n_total += 1

input.close()
os.system('chown -R root:reloadapache %s' % vhost_dir)
print "\n%d virtual hosts encontrados. %d comentados no creados| %d creados.\n" % (n_total, n_commented,num_servers)

arch = open(sys.argv[1], "rb")
contenido_original = arch.readlines()
arch.close()
del contenido_original[primer_host:(total_lineas+1)]

arch_modif = open(sys.argv[1], "w")
arch_modif.writelines(contenido_original)
arch_modif.writelines(archivo_comentado)
arch_modif.write("\nInclude vhost/*.conf\n")
arch_modif.writelines(n_include)
arch_modif.close()
os.system('/sbin/service httpd reload')
Nos vemos en la siguiente entrada!