hs.hsadmin/hsarback/src/de/hsadmin/mods/dom/DomainProcessorFactory.java
2012-09-20 15:40:42 +02:00

388 lines
19 KiB
Java

package de.hsadmin.mods.dom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.CompoundProcessor;
import de.hsadmin.core.qserv.CopyFileProcessor;
import de.hsadmin.core.qserv.CreateFileProcessor;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
import de.hsadmin.core.qserv.ProcessorException;
import de.hsadmin.core.qserv.ShellProcessor;
import de.hsadmin.core.qserv.TemplateProcessor;
import de.hsadmin.core.qserv.WaitingTasksProcessor;
import de.hsadmin.core.util.Config;
import de.hsadmin.mods.email.EMailAddress;
import de.hsadmin.mods.email.EMailAddressProcessorFactory;
import de.hsadmin.mods.pac.INetAddress;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
public class DomainProcessorFactory implements EntityProcessorFactory {
private static final String[] DW_STRUCTURE = new String[] { "htdocs", "htdocs-ssl", "subs", "subs/www", "subs-ssl", "subs-ssl/www", "cgi", "fastcgi", "cgi-ssl", "fastcgi-ssl", "etc", "var" };
private static final String[] SW_STRUCTURE = new String[] { "htdocs", "htdocs-ssl", "subs", "subs/www", "subs-ssl", "subs-ssl/www", "etc", "var" };
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity) throws ProcessorException {
String hiveName = entity.getHiveName();
Domain dom = (Domain) entity;
UnixUser domUser = dom.getUser();
Pac pac = domUser.getPac();
String pacName = pac.getName();
String domName = dom.getName();
Map<String, String> templateVars = new HashMap<String, String>();
templateVars.put("SIO", Long.toString(System.currentTimeMillis()/1000L));
templateVars.put("PAC", pacName);
templateVars.put("HIVE", pac.getHiveName());
templateVars.put("DOM_HOSTNAME", domName);
templateVars.put("DOM_USERNAME", domUser.getName());
templateVars.put("PAC_HOSTNAME", pacName + ".hostsharing.net");
templateVars.put("DOM_IPNUMBER", getCurrentIPAddress(pac));
templateVars.put("DOM_IPNUMBEREX", getOldIPAddress(pac));
WaitingTasksProcessor mainProcessor = new WaitingTasksProcessor(createHiveDNSSetupProcessor(domName, templateVars));
mainProcessor.appendProcessor(hiveName, createHiveEMailSetupProcessor(em, domName), "Setup EMail");
String pacInetAddr = pac.getCurINetAddr().getInetAddr();
Config config = Config.getInstance();
for (String queueName : config.getProperty("queues.dns").split(",")) {
mainProcessor.appendProcessor(queueName, createDNSServerSetupProcessor(domName, pacInetAddr), queueName + ".hostsharing.net");
}
for (String queueName : config.getProperty("queues.mail").split(",")) {
mainProcessor.appendProcessor(queueName, createMailinSetupProcessor(em, domName, pac), queueName + ".hostsharing.net");
}
templateVars = new HashMap<String, String>();
templateVars.put("PAC", pacName);
templateVars.put("HIVE", pac.getHiveName());
templateVars.put("DOM_HOSTNAME", domName);
templateVars.put("DOM_USERNAME", domUser.getName());
templateVars.put("PAC_HOSTNAME", pacName + ".hostsharing.net");
templateVars.put("DOM_IPNUMBER", getCurrentIPAddress(pac));
templateVars.put("DOM_IPNUMBEREX", getOldIPAddress(pac));
templateVars.put("DOMAIN", domName);
templateVars.put("USER_NAME", domUser.getComment());
mainProcessor.appendProcessor(hiveName, createApacheVHostSetupProcessor(em, dom, templateVars), "Setup Apache VHost");
if (dom.isPacDomain()) {
mainProcessor.appendProcessor(hiveName, createMovePacDomainContent(em, dom), "Move pac domain content");
}
return mainProcessor;
}
public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em, T entity) throws ProcessorException {
Domain dom = (Domain) entity;
UnixUser domUser = dom.getUser();
Pac pac = domUser.getPac();
String pacName = pac.getName();
String domName = dom.getName();
Map<String, String> templateVars = new HashMap<String, String>();
templateVars.put("PAC", pacName);
templateVars.put("HIVE", pac.getHiveName());
templateVars.put("DOM_HOSTNAME", domName);
templateVars.put("DOM_USERNAME", domUser.getName());
templateVars.put("PAC_HOSTNAME", pacName + ".hostsharing.net");
templateVars.put("DOM_IPNUMBER", getCurrentIPAddress(pac));
templateVars.put("DOM_IPNUMBEREX", getOldIPAddress(pac));
templateVars.put("DOMAIN", domName);
templateVars.put("USER_NAME", domUser.getComment());
WaitingTasksProcessor processor = new WaitingTasksProcessor(createApacheVHostSetupProcessor(em, dom, templateVars));
Config config = Config.getInstance();
for (String queueName : config.getProperty("queues.mail").split(",")) {
processor.appendProcessor(queueName, createPostgreyConfiguration(em), queueName + ".hostsharing.net");
}
return processor;
}
public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity) throws ProcessorException {
Domain dom = (Domain) entity;
String domName = dom.getName();
WaitingTasksProcessor mainProcessor = new WaitingTasksProcessor(
new CompoundProcessor(
createHiveEMailRemoveProcessor(domName),
createHiveDNSRemoveProcessor(domName)
)
);
Config config = Config.getInstance();
for (String queueName : config.getProperty("queues.dns").split(",")) {
mainProcessor.appendProcessor(queueName, createDNSServerRemoveProcessor(domName), queueName + ".hostsharing.net");
}
for (String queueName : config.getProperty("queues.mail").split(",")) {
mainProcessor.appendProcessor(queueName, createMailinDeleteProcessor(domName), queueName + ".hostsharing.net");
mainProcessor.appendProcessor(queueName, createPostgreyConfiguration(em), queueName + ".hostsharing.net");
}
mainProcessor.appendProcessor(dom.getHiveName(), createApacheVHostDeleteProcessor(dom), "remove apache vhost");
return mainProcessor;
}
private Processor createHiveDNSSetupProcessor(String domName, Map<String, String> templateVars)
throws ProcessorException {
String zonefileTargetPath = "/etc/bind/pri." + domName;
Processor zonefileTemplateProcessor =
new TemplateProcessor("/de/hsadmin/mods/dom/zonefile.jtpl", templateVars, zonefileTargetPath, false);
Processor zonefileACLProcessor =
new ShellProcessor("chown root:bind " + zonefileTargetPath + " && chmod 644 " + zonefileTargetPath);
Processor prizonesFileProcessor =
new ShellProcessor("echo 'zone \"" + domName + "\" { type master; file \"pri." + domName + "\"; };' >>/etc/bind/named.pri-zones" +
" && sort /etc/bind/named.pri-zones | uniq >/etc/bind/named.pri-zones.tmp" +
" && mv /etc/bind/named.pri-zones.tmp /etc/bind/named.pri-zones");
Processor dnsReloadProcessor = new ShellProcessor("invoke-rc.d bind9 reload");
Processor dnsSetupProcessor =
new CompoundProcessor(zonefileTemplateProcessor, zonefileACLProcessor, prizonesFileProcessor, dnsReloadProcessor);
return dnsSetupProcessor;
}
private ShellProcessor createHiveDNSRemoveProcessor(String domName) {
return new ShellProcessor("grep -v '\"pri." + domName + "\"' /etc/bind/named.pri-zones > /etc/bind/named.pri-zones.tmp" +
" && mv /etc/bind/named.pri-zones.tmp /etc/bind/named.pri-zones" +
" && rm /etc/bind/pri." + domName +
" && invoke-rc.d bind9 reload");
}
private CompoundProcessor createHiveEMailSetupProcessor(EntityManager em, String domName) {
EMailAddressProcessorFactory eMailAddressProcessorFactory = new EMailAddressProcessorFactory();
CompoundProcessor emailAdrProcessor = new CompoundProcessor();
Query query = em.createQuery(
"SELECT adr FROM " +
EMailAddress.class.getAnnotation(javax.persistence.Entity.class).name() + " adr " +
"WHERE adr.domain.name='" + domName + "'");
List<?> resultList = query.getResultList();
for (Object obj : resultList) {
EMailAddress eMailAddress = (EMailAddress) obj;
emailAdrProcessor.appendProcessor(eMailAddressProcessorFactory.createCreateProcessor(em, eMailAddress));
}
return emailAdrProcessor;
}
private ShellProcessor createHiveEMailRemoveProcessor(String domName) {
return new ShellProcessor(
"postmap -d '" + domName + "' /etc/postfix-mailin/virtual && " +
"for KEY in $(postmap -s /etc/postfix-mailin/virtual|grep '@" + domName + "\\s'|cut -f1); " +
"do postmap -d $KEY /etc/postfix-mailin/virtual; done"
);
}
private Processor createDNSServerSetupProcessor(String domName, String pacInetAddr) {
Processor seczonesFileProcessor;
seczonesFileProcessor =
new ShellProcessor("echo 'zone \"" + domName + "\" { type slave; file \"sec." + domName + "\"; masters { " + pacInetAddr + "; }; };' >>/etc/bind/named-hsh.conf" +
" && sort /etc/bind/named-hsh.conf | uniq >/etc/bind/named-hsh.conf.tmp" +
" && mv /etc/bind/named-hsh.conf.tmp /etc/bind/named-hsh.conf" +
" && invoke-rc.d bind9 reload");
return seczonesFileProcessor;
}
private Processor createDNSServerRemoveProcessor(String domName) {
return new ShellProcessor("grep -v '\"sec." + domName + "\"' /etc/bind/named-hsh.conf >/etc/bind/named-hsh.conf.tmp" +
// TODO sed -e'/sec.abc.example.com/d' -i /etc/bind/named-hsh.conf
" && mv /etc/bind/named-hsh.conf.tmp /etc/bind/named-hsh.conf" +
" && rm /var/cache/bind/sec." + domName +
" && invoke-rc.d bind9 reload");
}
private Processor createMailinSetupProcessor(EntityManager em, String domName, Pac pac) throws ProcessorException {
String inetAddr = pac.getCurINetAddr().getInetAddr();
return new CompoundProcessor(
createPostgreyConfiguration(em),
new ShellProcessor("postmap -r -i /etc/postfix-mailin/relaydomains",
domName + " anything\n" +
"." + domName + " anything\n"),
new ShellProcessor("postmap -r -i /etc/postfix-mailin/transport",
domName + " smtp:" + inetAddr + ":225\n" +
"." + domName + " smtp:" + inetAddr + ":225\n")
);
}
private Processor createPostgreyConfiguration(EntityManager em) throws ProcessorException {
ArrayList<Map<String, String>> domsMaps = new ArrayList<Map<String, String>>();
Query query = em.createQuery("SELECT d FROM Domains d WHERE d.domainoptions.name = :option");
query.setParameter("option", "nogreylisting");
List<?> result = query.getResultList();
for (Object dom : result) {
if (dom instanceof Domain) {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("DOM", ((Domain) dom).getName());
domsMaps.add(hashMap);
}
}
return new CompoundProcessor(
new TemplateProcessor("/de/hsadmin/mods/dom/postgrey-whitelist-recipients.jtpl",
new HashMap<String, String>(),
domsMaps.iterator(), "/etc/postgrey/whitelist_recipients.tmp", true),
new ShellProcessor(" ( diff -q /etc/postgrey/whitelist_recipients.tmp /etc/postgrey/whitelist_recipients && rm /etc/postgrey/whitelist_recipients.tmp ) " +
"|| ( mv /etc/postgrey/whitelist_recipients.tmp /etc/postgrey/whitelist_recipients && invoke-rc.d postgrey reload )")
);
}
private Processor createMailinDeleteProcessor(String domName) {
Processor mailQueueProcessor = new ShellProcessor(
"postmap -d '" + domName + "' /etc/postfix-mailin/relaydomains && " +
"postmap -d '" + domName + "' /etc/postfix-mailin/transport && " +
"postmap -d '." + domName + "' /etc/postfix-mailin/relaydomains && " +
"postmap -d '." + domName + "' /etc/postfix-mailin/transport");
return mailQueueProcessor;
}
private CompoundProcessor createDomainDirectoriesProcessor(Domain dom, Map<String, String> templateVars) throws ProcessorException {
UnixUser domUser = dom.getUser();
String domName = dom.getName();
Pac pac = domUser.getPac();
boolean dynamicWeb = pac.isDynamicWeb() || dom.isPacDomain();
String pacName = pac.getName();
String homeDir = domUser.getHomedir();
String domsDir = homeDir + "/doms";
String userName = domUser.getName();
String domainDir = domsDir + "/" + dom.getName();
String[] subDirs = dynamicWeb ? DW_STRUCTURE : SW_STRUCTURE;
String httpdRights = "";
if (pacName != userName) {
httpdRights =
"chgrp httpd " + homeDir + " && " +
"chmod g+rx " + homeDir + " && ";
}
Processor mkDomainDirProzessor =
new ShellProcessor( httpdRights +
"chgrp httpd " + homeDir + " && " +
"chmod g+rx " + homeDir + " && " +
"mkdir --mode=1550 --parents " + domsDir + " && " +
"chown httpd:" + pacName + " " + domsDir + " && " +
"mkdir --mode=750 --parents " + domainDir + " && " +
"chown " + userName + ":httpd " + domainDir
);
CompoundProcessor domDirsProcessor = new CompoundProcessor(mkDomainDirProzessor);
for (String subDir : subDirs) {
domDirsProcessor.appendProcessor(new ShellProcessor(
"mkdir --mode=755 --parents " + domainDir + "/" + subDir + " && " +
"chown " + userName + ":" + pacName + " " + domainDir + "/" + subDir
));
}
templateVars.put("PROTOCOL", "http");
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/htaccess.jtpl", templateVars, domainDir + "/htdocs/.htaccess", userName, pacName, "644", false)
);
templateVars.put("PROTOCOL", "https");
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/htaccess.jtpl", templateVars, domainDir + "/htdocs-ssl/.htaccess", userName, pacName, "644", false)
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/index.html.jtpl", templateVars, domainDir + "/subs/www/index.html", userName, pacName, "644", false)
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/index.html.jtpl", templateVars, domainDir + "/subs-ssl/www/index.html", userName, pacName, "644", false)
);
if (dynamicWeb) {
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/test.cgi.jtpl", templateVars, domainDir + "/cgi/test.cgi", userName, pacName, "755", false)
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/test.cgi.jtpl", templateVars, domainDir + "/cgi-ssl/test.cgi", userName, pacName, "755", false)
);
domDirsProcessor.appendProcessor(
new CopyFileProcessor("/usr/local/src/phpstub/phpstub", domainDir + "/fastcgi/phpstub", userName, pacName, "755")
);
domDirsProcessor.appendProcessor(
new CopyFileProcessor("/usr/local/src/phpstub/phpstub", domainDir + "/fastcgi-ssl/phpstub", userName, pacName, "755")
);
}
domDirsProcessor.appendProcessor(
new ShellProcessor("ln -s " + domainDir + " /home/doms/ && " +
"chown --no-dereference " + userName + ":httpd /home/doms/" + domName
+ " && " + "chown " + userName + ":httpd /home/doms/" + domName + "/")
);
return domDirsProcessor;
}
private Processor createApacheVHostSetupProcessor(EntityManager em, Domain dom, Map<String, String> templateVars)
throws ProcessorException {
String domName = dom.getName();
int level = domName.split("\\.").length;
String linkPrefix = Integer.toString(100 - level);
String pac = dom.getUser().getPac().getName();
Query query = em.createQuery("SELECT d FROM Domains d WHERE d.domainoptions.name = :option AND d.name = :domname");
query.setParameter("option", "nohtdocsfallback");
query.setParameter("domname", dom.getName());
List<?> result = query.getResultList();
List<Map<String, String>> iterateMaps = new ArrayList<Map<String, String>>();
if (!result.isEmpty()) {
iterateMaps.add(new HashMap<String, String>());
}
Processor domSetupProcessor = new CompoundProcessor(
createDomainDirectoriesProcessor(dom, templateVars),
new CreateFileProcessor(selectVHostTemplate(dom), templateVars, "/etc/apache2/sites-available/" + domName + ".tmp", "root", "root", "644", true),
new ShellProcessor("ls /etc/apache2/pems/" + pac + ".pem >/dev/null 2>&1 " +
"&& sed -i '/SSLCertificate.*default/d' " + "/etc/apache2/sites-available/" + domName + ".tmp" +
" && (ls /etc/apache2/pems/" + pac + ".chain.pem >/dev/null 2>&1 || sed -i '/SSLCertificateChain.*" + pac + "/d' " + "/etc/apache2/sites-available/" + domName + ")" +
" || sed -i '/SSLCertificate.*" + pac + "/d' " + "/etc/apache2/sites-available/" + domName + ".tmp"),
new ShellProcessor(
" ( diff -q /etc/apache2/sites-available/" + domName + ".tmp /etc/apache2/sites-available/" + domName + " && rm /etc/apache2/sites-available/" + domName + ".tmp ) " +
" || ( mv /etc/apache2/sites-available/" + domName + ".tmp /etc/apache2/sites-available/" + domName +
" && rm -f /etc/apache2/sites-enabled/" + linkPrefix + "-" + domName +
" && ln -sf /etc/apache2/sites-available/" + domName + " /etc/apache2/sites-enabled/" + linkPrefix + "-" + domName +
" && invoke-rc.d apache2 reload >/dev/null 2>&1 ) ")
);
return domSetupProcessor;
}
private Processor createApacheVHostDeleteProcessor(Domain dom) {
String domName = dom.getName();
int level = domName.split("\\.").length;
String linkPrefix = Integer.toString(100 - level);
Processor vhostDelProcessor =
new ShellProcessor("rm /home/doms/" + domName +
" && rm /etc/apache2/sites-enabled/" + linkPrefix + "-" + domName +
" && rm /etc/apache2/sites-available/" + domName +
" && rm -rf " + dom.getUser().getHomedir() + "/doms/" + domName +
" && invoke-rc.d apache2 reload >/dev/null 2>&1");
return vhostDelProcessor;
}
private Processor createMovePacDomainContent(EntityManager em, Domain dom) {
Pac pac = dom.getUser().getPac();
String pacDir = "/home/pacs/" + pac.getName();
String domDir = pacDir + "/doms/" + pac.getName() + ".hostsharing.net";
String[] sourceDirs = new String[] { "web", "web-ssl", "cgi", "cgi-ssl", "fastcgi", "fastcgi-ssl" } ;
String[] targetDirs = new String[] { "htdocs", "htdocs-ssl", "cgi", "cgi-ssl", "fastcgi", "fastcgi-ssl" } ;
CompoundProcessor processor = new CompoundProcessor(
new ShellProcessor("rm -rf " + domDir + "/subs " + domDir + "/htdocs/.htaccess "
+ domDir + "/subs-ssl " + domDir + "/htdocs-ssl/.htaccess "));
for (int idx = 0; idx < sourceDirs.length; idx++) {
processor.appendProcessor(
new ShellProcessor("shopt -s dotglob && ls " + pacDir + "/" + sourceDirs[idx] + " >/dev/null 2>&1" +
" && mv " + pacDir + "/" + sourceDirs[idx] + "/* " + domDir + "/" + targetDirs[idx] + "/ " +
" && ( rmdir " + pacDir + "/" + sourceDirs[idx] + " || rm " + pacDir + "/" + sourceDirs[idx] + " ) " +
" || echo 'directory " + pacDir + "/" + sourceDirs[idx] + " not found'"));
}
return processor;
}
private String selectVHostTemplate(Domain dom) {
String domName = dom.getName();
UnixUser user = dom.getUser();
Pac pac = user.getPac();
if (domName.equals(pac.getName() + ".hostsharing.net")) {
return "/de/hsadmin/mods/dom/httpd-vhost-dynamic.jtpl";
}
if (pac.isDynamicWeb() || dom.isPacDomain()) {
return "/de/hsadmin/mods/dom/httpd-vhost-dynamic.jtpl";
}
return "/de/hsadmin/mods/dom/httpd-vhost-static.jtpl";
}
private String getCurrentIPAddress(Pac pac) {
return pac.getCurINetAddr().getInetAddr();
}
private String getOldIPAddress(Pac pac) {
INetAddress oldINetAddr = pac.getOldINetAddr();
if (oldINetAddr != null) {
return oldINetAddr.getInetAddr();
} else {
return getCurrentIPAddress(pac);
}
}
}