HSAdmin Backend Domains, E-Mail, Datenbanken
Peter Hormanns
2012-01-04 98477776a8e63a9ce0960099854c4dbd3df4249c
fix #79 with testcase
2 files added
8 files modified
364 ■■■■■ changed files
hsarback/build.xml 2 ●●● patch | view | raw | blame | history
hsarback/src/de/hsadmin/core/qserv/CommandShell.java 174 ●●●● patch | view | raw | blame | history
hsarback/src/de/hsadmin/core/qserv/ShellException.java 19 ●●●●● patch | view | raw | blame | history
hsarback/src/de/hsadmin/core/qserv/ShellProcessor.java 27 ●●●● patch | view | raw | blame | history
hsarback/src/de/hsadmin/mods/dom/DomainProcessorFactory.java 5 ●●●●● patch | view | raw | blame | history
hsarback/src/de/hsadmin/mods/dom/httpd-vhost-dynamic.jtpl 2 ●●●●● patch | view | raw | blame | history
hsarback/src/de/hsadmin/mods/dom/httpd-vhost-static.jtpl 2 ●●●●● patch | view | raw | blame | history
hsarback/test/de/hsadmin/remote/ContinuousIntegrationTest.java 26 ●●●●● patch | view | raw | blame | history
hsarback/test/de/hsadmin/remote/InitDataTest.java 39 ●●●●● patch | view | raw | blame | history
hsarback/test/de/hsadmin/remote/SSLCertDomainTest.java 68 ●●●●● patch | view | raw | blame | history
hsarback/build.xml
@@ -154,7 +154,7 @@
                <pathelement path="/usr/share/java/junit4.jar"/>
            </classpath>
            <formatter type="xml"/>
            <test name="de.hsadmin.remote.RemoteTest" todir="${build.home}/junit" />
            <test name="de.hsadmin.remote.ContinuousIntegrationTest" todir="${build.home}/junit" />
        </junit>
    </target>
    
hsarback/src/de/hsadmin/core/qserv/CommandShell.java
@@ -7,151 +7,69 @@
import java.io.OutputStream;
import java.io.PrintWriter;
public class CommandShell
{
    private static boolean bExecute = true;     // really execute or just store command and stdin?
    private static String executedCommands;     // stored command and stdin
    private static String[] aEnvironment;         // stored environment
    /** Set mode of real execution or just storing the command and stdin.
     *
     *     @param bExec
     *         specifies whether shell commands should really be executed (true) or not (false)
     */
    public static void setExecute( boolean bExec )
    {
        bExecute = bExec;
    }
public class CommandShell {
    
    /** Returns and clears the last command which should have been executed.
     *
     * @return
     *         Last command, plus "<<EOF\n" + stdin + "EOF" if stdin was given.
     */
    public static String popLastCommand()
    {
        String aLastCommand = executedCommands;
        executedCommands = null;
        return aLastCommand != null ? aLastCommand.trim() : null;
    }
    /** Returns and clears the environment which ist currently used for commands.
     *
     * @return
     *         Most recent command environment.
     */
    public static String[] popEnvironment()
    {
        String[] aLastEnvironment = aEnvironment;
        aEnvironment = null;
        return aLastEnvironment;
    public static String execute(String command) throws ShellException {
        return execute(command, null);
    }
    public static void setEnvironment( String[] env )
    {
        aEnvironment = env;
    }
    /** Execute the given command by a shell.
     *
     *     @throws ShellException
     *         if an execution error has occured.
     */
    public static String execute( String command )
        throws ShellException
    {
        return execute( command, null );
    }
    /** Execute the given command by a shell including stdin.
     *
     *     @throws ShellException
     *         if an execution error has occured.
     */
    public static String execute( String command, String stdInput )
        throws ShellException
    {
    public static String execute(String command, String stdInput) throws ShellException {
        Process backend = null;
        String callOutput = null;
        int exitCode = 0;
        try
        {
        try {
            String logCommand = command;
            if ( stdInput != null ) //&& stdInput.length() > 0 )
            if (stdInput != null)  {
                logCommand += "<<EOF\n" + stdInput + "EOF";
            logCommand += "\n";
            // add to command buffer (used in tests)
            if ( executedCommands == null )
                executedCommands = logCommand;
            else
                executedCommands += logCommand;
            if ( bExecute )
            {
                // TODO logging
                System.out.println("--- shell command: ---" );
                System.out.println( logCommand );
                String[] cmdArray = { "/bin/bash", "-c", command };
                backend = Runtime.getRuntime().exec(cmdArray, aEnvironment);
                if ( stdInput != null )
                {
                    OutputStream stdInputStream = backend.getOutputStream();
                    PrintWriter stdInputWriter = new PrintWriter(stdInputStream);
                    stdInputWriter.print(stdInput);
                    stdInputWriter.close();
                    stdInputStream.close();
                }
                callOutput = readProcessStream(backend.getInputStream());
                exitCode = backend.waitFor();
                // TODO logging
                System.out.println( "RET: " + exitCode );
                if (exitCode != 0)
                {
                    String aErr = readProcessStream(backend.getErrorStream());
                    // TODO logging
                    System.out.println( "ERR: " + aErr  );
                    System.out.println("--- done. ---" );
                    throw new ShellException( exitCode, aErr );
                }
                // TODO logging
                System.out.println("--- done. ---" );
            }
        }
        catch (IOException e)
        {
            throw new ShellException();
        }
        catch (InterruptedException e)
        {
            throw new ShellException();
            logCommand += "\n";
            // TODO logging
            System.out.println("--- shell command: ---");
            System.out.println(logCommand);
            String[] cmdArray = { "/bin/bash", "-c", command };
            backend = Runtime.getRuntime().exec(cmdArray);
            if (stdInput != null) {
                OutputStream stdInputStream = backend.getOutputStream();
                PrintWriter stdInputWriter = new PrintWriter(stdInputStream);
                stdInputWriter.print(stdInput);
                stdInputWriter.close();
                stdInputStream.close();
            }
            callOutput = readProcessStream(backend.getInputStream());
            exitCode = backend.waitFor();
            // TODO logging
            System.out.println("RET: " + exitCode);
            if (exitCode != 0) {
                String aErr = readProcessStream(backend.getErrorStream());
                // TODO logging
                System.out.println("ERR: " + aErr);
                System.out.println("--- done. ---");
                throw new ShellException(aErr);
            }
            // TODO logging
            System.out.println("--- done. ---");
        } catch (IOException e) {
            throw new ShellException(e);
        } catch (InterruptedException e) {
            throw new ShellException(e);
        }
        if ( callOutput != null )
        {
            // int nLen = callOutput.length();
            // if ( nLen > 0 && callOutput.charAt(nLen-1) == '\n' )
            // callOutput = callOutput.substring(0, nLen-1);
        if (callOutput != null) {
            return callOutput.trim();
        }
        return null;
    }
    private static String readProcessStream(InputStream stream) throws IOException
    {
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(stream));
    private static String readProcessStream(InputStream stream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        StringBuffer textBuff = new StringBuffer();
        String textLine = reader.readLine();
        while (textLine != null)
        {
        while (textLine != null) {
            textBuff.append(textLine);
            textBuff.append('\n');
            textLine = reader.readLine();
hsarback/src/de/hsadmin/core/qserv/ShellException.java
@@ -1,19 +1,14 @@
package de.hsadmin.core.qserv;
public class ShellException
        extends Exception
{
    private static final long serialVersionUID = 8335020360721047849L;
public class ShellException extends Exception {
    int nExitCode;
    public ShellException()
    {
    private static final long serialVersionUID = 5499293305075489652L;
    public ShellException(String message) {
        super(message);
    }
    public ShellException( int exitCode, String message )
    {
        super( message );
        nExitCode = exitCode;
    public ShellException(Throwable e) {
        super(e);
    }
}
hsarback/src/de/hsadmin/core/qserv/ShellProcessor.java
@@ -13,47 +13,26 @@
    private static final long serialVersionUID = -649045174380048818L;
    private String aSystemCall;
    private String[] aEnv;
    private String aInput;
    private String aOutput;
    private String aErrors;
    /**
     * Constructor for a queue entry which executes a system call.
     *
     * @param aSystemCall
     *            the system call to be executed
     */
    public ShellProcessor(String aSystemCall) {
        this(aSystemCall, null, null);
    }
    /**
     * Constructor for a queue entry which executes a system call with stdin
     * data.
     *
     * @param aSystemCall
     *            the system call to be executed
     * @param aInput
     *            data for stdin of the system call
     */
    public ShellProcessor(String aSystemCall, String aInput) {
        this.aSystemCall = aSystemCall;
        this.aInput = aInput;
    }
    public ShellProcessor(String aSystemCall, String[] aEnv, String aInput) {
    public ShellProcessor(String aSystemCall) {
        this.aSystemCall = aSystemCall;
        this.aEnv = aEnv;
        this.aInput = aInput;
        this.aInput = null;
    }
    public Object process() throws ProcessorException {
        try {
            CommandShell.setEnvironment(aEnv);
            aOutput = CommandShell.execute(aSystemCall, aInput);
            return aOutput;
        } catch (ShellException aExc) {
            aErrors = aExc.getMessage();
            aExc.printStackTrace(System.err); // Logging
            throw new ProcessorException(aExc);
        }
hsarback/src/de/hsadmin/mods/dom/DomainProcessorFactory.java
@@ -249,9 +249,14 @@
    private Processor createApacheVHostSetupProcessor(Domain dom, Map<String, String> templateVars) 
                throws ProcessorException {
        String domName = dom.getName();
        String pac = dom.getUser().getPac().getName();
        Processor domSetupProcessor = new CompoundProcessor(
            createDomainDirectoriesProcessor(dom, templateVars),
            new CreateFileProcessor(selectVHostTemplate(dom), templateVars, "/etc/apache2/sites-generated/" + domName, "root", "root", "644"),
            new ShellProcessor("ls /etc/apache2/pem/" + pac + ".pem >/dev/null 2>&1 " +
                    "&& sed -i '/SSLCertificate.*default/d' " + "/etc/apache2/sites-generated/" + domName +
                    " && (ls /etc/apache2/pem/" + pac + ".chain.pem >/dev/null 2>&1 || sed -i '/SSLCertificateChain.*" + pac + "/d' " + "/etc/apache2/sites-generated/" + domName + ")" +
                    " || sed -i '/SSLCertificate.*" + pac + "/d' " + "/etc/apache2/sites-generated/" + domName),
            new ShellProcessor(
                    "ln -sf /etc/apache2/sites-generated/" + domName + " /etc/apache2/sites-enabled/010-" + domName + 
                    " && invoke-rc.d apache2 reload >/dev/null 2>&1")
hsarback/src/de/hsadmin/mods/dom/httpd-vhost-dynamic.jtpl
@@ -62,6 +62,8 @@
    SSLEngine On
    SSLCertificateFile /etc/apache2/pems/default.pem
    SSLCertificateChainFile /etc/apache2/pems/default.chain.pem
    SSLCertificateFile /etc/apache2/pems/{PAC}.pem
    SSLCertificateChainFile /etc/apache2/pems/{PAC}.chain.pem
    DocumentRoot /home/doms/{DOM_HOSTNAME}/htdocs-ssl
hsarback/src/de/hsadmin/mods/dom/httpd-vhost-static.jtpl
@@ -52,6 +52,8 @@
    SSLEngine On
    SSLCertificateFile /etc/apache2/pems/default.pem
    SSLCertificateChainFile /etc/apache2/pems/default.chain.pem
    SSLCertificateFile /etc/apache2/pems/{PAC}.pem
    SSLCertificateChainFile /etc/apache2/pems/{PAC}.chain.pem
    DocumentRoot /home/doms/{DOM_HOSTNAME}/htdocs-ssl
hsarback/test/de/hsadmin/remote/ContinuousIntegrationTest.java
New file
@@ -0,0 +1,26 @@
package de.hsadmin.remote;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
    InitDataTest.class,
    RoleTest.class,
    MysqlUserTest.class,
    MysqlDbTest.class,
    PgsqlUserTest.class,
    PgsqlDbTest.class,
    PacTest.class,
    UnixUserTest.class,
    EMailAliasTest.class,
    DomainTest.class,
    EMailAddressTest.class,
    SSLCertDomainTest.class
//    CustomerTest.class,
//    QueueTaskTest.class
})
public class ContinuousIntegrationTest {
}
hsarback/test/de/hsadmin/remote/InitDataTest.java
@@ -62,9 +62,6 @@
                setParams };
        try {
            client.execute(CUST_MODULE + ".add", params);
//            Object execute = client.execute(CUST_MODULE + ".add", params);
//            Map<?, ?> result = (Map<?, ?>) execute;
//            System.out.println(result);
            assertEquals(membersCount + 1, getMembersCount());
        } catch (XmlRpcException e) {
            fail(e.getMessage());
@@ -165,42 +162,6 @@
            fail(e.getMessage());
        }
        assertEquals(count + 1, getUsersCount());
    }
//    @Test
    public void testDelPac() {
        int count = getPacsCount();
        String user = "ad";
        String grantingTicketURL = cas.getGrantingTicketURL(user);
        Map<String, String> whereParams = new HashMap<String, String>();
        whereParams.put("name", "aaa00");
        Object[] params = new Object[] { user,
                cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
                whereParams };
        try {
            client.execute(PAC_MODULE + ".delete", params);
        } catch (XmlRpcException e) {
            fail(e.getMessage());
        }
        assertEquals(count - 1, getPacsCount());
    }
//    @Test
    public void testDelMember() {
        int count = getMembersCount();
        String user = "ad";
        String grantingTicketURL = cas.getGrantingTicketURL(user);
        Map<String, String> whereParams = new HashMap<String, String>();
        whereParams.put("membercode", "hsh00-aaa");
        Object[] params = new Object[] { user,
                cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
                whereParams };
        try {
            client.execute(CUST_MODULE + ".delete", params);
        } catch (XmlRpcException e) {
            fail(e.getMessage());
        }
        assertEquals(count - 1, getMembersCount());
    }
    private int getMembersCount() {
hsarback/test/de/hsadmin/remote/SSLCertDomainTest.java
New file
@@ -0,0 +1,68 @@
package de.hsadmin.remote;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import de.hsadmin.core.qserv.CommandShell;
import de.hsadmin.core.qserv.ShellException;
import de.hsadmin.core.util.Config;
public class SSLCertDomainTest {
    private static final String MODULE = "domain";
    private XmlRpcClient client;
    private RemoteCASHelper cas;
    private Config config;
    @Before
    public void setUp() throws Exception {
        client = RemoteTestHelper.getClient();
        cas = new RemoteCASHelper();
        config = Config.getInstance();
    }
    @After
    public void tearDown() throws Exception {
        client = null;
        cas = null;
        config = null;
    }
    @Test
    public void testSSLCertWithoutChain() {
        String user = "ad";
        String grantingTicketURL = cas.getGrantingTicketURL(user);
        Map<String, String> setParams = new HashMap<String, String>();
        setParams.put("name", "aaa02");
        setParams.put("hive", "h81");
        setParams.put("customer", config.getProperty("accountprefix.customer") + "-aaa");
        setParams.put("basepac", "DW/B");
        setParams.put("curinetaddr", "176.9.242.75");
        Object[] params = new Object[] { user,
                cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
                setParams };
        try {
            Object execute = client.execute(MODULE + ".add", params);
            assertTrue(execute instanceof Map<?, ?>);
            Thread.sleep(5000L);
            CommandShell.execute("grep 'SSLCertificateChainFile' /var/local/lxc/hive/etc/apache2/sites-generated/aaa02.hostsharing.net");
            fail("ShellException expected");
        } catch (XmlRpcException e) {
            fail(e.getMessage());
        } catch (ShellException e) {
        } catch (InterruptedException e) {
            fail(e.getMessage());
        }
    }
}