Jelajahi Sumber

docker updates and onejar refactoring

jrivard@gmail.com 6 tahun lalu
induk
melakukan
9abbf177a1

+ 1 - 1
data-service/pom.xml

@@ -13,7 +13,7 @@
 
     <packaging>war</packaging>
 
-    <name>PWM Password Self Service: Data Service</name>
+    <name>PWM Password Self Service: Data Service WAR</name>
 
     <licenses>
         <license>

+ 13 - 0
docker/pom.xml

@@ -51,6 +51,19 @@
                                 <format>docker</format>
                                 <ports>8443</ports>
                             </container>
+                            <extraDirectory>
+                                <path>${project.basedir}/src/main/image-files</path> <!-- Copies files from 'src/main/custom-extra-dir' -->
+                                <permissions>
+                                    <permission>
+                                        <file>/app/startup.sh</file>
+                                        <mode>755</mode> <!-- Read/write for owner, read-only for group/other -->
+                                    </permission>
+                                    <permission>
+                                        <file>/app/command.sh</file>
+                                        <mode>755</mode> <!-- Read/write for owner, read-only for group/other -->
+                                    </permission>
+                                </permissions>
+                            </extraDirectory>
                         </configuration>
                     </execution>
                 </executions>

+ 0 - 23
docker/src/main/docker/Dockerfile

@@ -1,23 +0,0 @@
-FROM adoptopenjdk/openjdk10
-MAINTAINER Jason Rivard
-
-# setup environment
-RUN mkdir /config ; mkdir /appliance
-ENV PWM_APPLICATIONPATH /config
-ENV PWM_APPLICATIONFLAGS Appliance,ManageHttps
-
-VOLUME /config
-EXPOSE 8443
-
-# copy war
-COPY onejar/pwm-onejar.jar /appliance/pwm-onejar.jar
-
-# copy scripts
-COPY startup.sh /appliance/startup.sh
-RUN chmod a+x /appliance/startup.sh;
-
-VOLUME /config
-EXPOSE 8443
-
-WORKDIR /appliance
-CMD ./startup.sh

+ 0 - 3
docker/src/main/docker/java.vmoptions

@@ -1,3 +0,0 @@
--server
--Xmx1g
--Xms1g

+ 0 - 9
docker/src/main/docker/startup.sh

@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-#Docker startup script
-
-#start onejar
-cd /appliance
-
-JAVA_OPTS="$(sed 's/./&/' java.vmoptions | tr '\n' ' ')"
-
-java $JAVA_OPTS -jar pwm-onejar.jar -applicationPath /config

+ 6 - 0
docker/src/main/image-files/app/command.sh

@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# Run command line shell environment inside the docker container.  Execute using
+# docker exec -it <container name> /application/command.sh
+
+java -jar /app/libs/pwm-onejar*.jar -applicationPath /config -command $1 $2 $3 $4 $5 $6 $7 $8 $9
+

+ 0 - 0
docker/src/main/jib/application/java.vmoptions → docker/src/main/image-files/app/java.vmoptions


+ 1 - 1
docker/src/main/jib/application/startup.sh → docker/src/main/image-files/app/startup.sh

@@ -4,4 +4,4 @@
 JAVA_OPTS="$(sed 's/./&/' java.vmoptions | tr '\n' ' ')"
 export JAVA_OPTS
 
-java -jar /app/libs/pwm-onejar-${project.version}.jar $JAVA_OPTS
+java -jar /app/libs/pwm-onejar*.jar $JAVA_OPTS -applicationPath /config

+ 0 - 0
docker/src/main/jib/config/readme.txt → docker/src/main/image-files/config/readme.txt


+ 1 - 1
onejar/pom.xml

@@ -13,7 +13,7 @@
 
     <packaging>jar</packaging>
 
-    <name>PWM Password Self Service: Executable JAR</name>
+    <name>PWM Password Self Service: Executable Server JAR</name>
 
     <properties>
         <project.root.basedir>${project.basedir}/..</project.root.basedir>

+ 27 - 17
onejar/src/main/java/password/pwm/onejar/ArgumentParser.java

@@ -91,6 +91,12 @@ public class ArgumentParser
                 {
                     argumentMap = mapFromCommandLine( commandLine );
                 }
+
+                if ( argumentMap.containsKey( Argument.command ) && argumentMap.get( Argument.command ) == null )
+                {
+                    throw new ArgumentParserException( Argument.command.name() + " requires arguments" );
+                }
+
                 final OnejarConfig onejarConfig;
                 try
                 {
@@ -145,16 +151,17 @@ public class ArgumentParser
                 if ( commandLine.hasOption( option.getOpt() ) )
                 {
                     final Argument argument = Argument.valueOf( option.getOpt() );
-                    if ( option.getArgs() > 1 )
                     {
                         final String[] values = commandLine.getOptionValues( option.getOpt() );
-                        final String joined = String.join( " ", values );
-                        map.put( argument, joined );
-                    }
-                    else
-                    {
-                        final String value = commandLine.getOptionValue( option.getOpt() );
-                        map.put( argument, value );
+                        if ( values != null )
+                        {
+                            final String joined = String.join( " ", values );
+                            map.put( argument, joined );
+                        }
+                        else
+                        {
+                            map.put( argument, null );
+                        }
                     }
                 }
             }
@@ -216,14 +223,17 @@ public class ArgumentParser
         final String localAddress = argumentMap.getOrDefault( Argument.localAddress, Resource.defaultLocalAddress.getValue() );
         onejarConfig.localAddress( localAddress );
 
-        try
+        if ( !argumentMap.containsKey( Argument.command ) )
         {
-            final ServerSocket socket = new ServerSocket( port, 100, InetAddress.getByName( localAddress ) );
-            socket.close();
-        }
-        catch ( Exception e )
-        {
-            throw new ArgumentParserException( "port or address conflict: " + e.getMessage() );
+            try
+            {
+                final ServerSocket socket = new ServerSocket( port, 100, InetAddress.getByName( localAddress ) );
+                socket.close();
+            }
+            catch ( Exception e )
+            {
+                throw new ArgumentParserException( "port or address conflict: " + e.getMessage() );
+            }
         }
 
         if ( argumentMap.containsKey( Argument.workPath ) )
@@ -238,7 +248,6 @@ public class ArgumentParser
         if ( argumentMap.containsKey( Argument.command ) )
         {
             final String value = argumentMap.get( Argument.command );
-            System.out.println( "cmddetected" );
             onejarConfig.execCommand( value );
         }
 
@@ -260,7 +269,8 @@ public class ArgumentParser
     }
 
 
-    private static File parseFileOption( final Map<Argument, String> argumentMap, final Argument argName ) throws ArgumentParserException
+    private static File parseFileOption( final Map<Argument, String> argumentMap, final Argument argName )
+            throws ArgumentParserException
     {
         if ( !argumentMap.containsKey( argName ) )
         {

+ 19 - 26
onejar/src/main/java/password/pwm/onejar/TomcatOnejarRunner.java

@@ -100,9 +100,10 @@ public class TomcatOnejarRunner
         explodeWar( onejarConfig );
         out( "deployed war" );
 
+        final Properties tlsProperties;
         try
         {
-            generatePwmKeystore( onejarConfig );
+            tlsProperties = this.executeOnejarHelper( onejarConfig );
             out( "keystore generated" );
         }
         catch ( Exception e )
@@ -143,7 +144,7 @@ public class TomcatOnejarRunner
 
         try
         {
-            tomcat.setConnector( makeConnector( onejarConfig ) );
+            tomcat.setConnector( makeConnector( onejarConfig, tlsProperties ) );
             tomcat.start();
             out( "tomcat started in " + Duration.between( Instant.now(), startTime ).toString() );
         }
@@ -180,7 +181,7 @@ public class TomcatOnejarRunner
     }
 
 
-    private Connector makeConnector( final OnejarConfig onejarConfig )
+    private Connector makeConnector( final OnejarConfig onejarConfig, final Properties tlsProperties )
             throws Exception
     {
         final Connector connector = new Connector( "HTTP/1.1" );
@@ -198,7 +199,6 @@ public class TomcatOnejarRunner
         connector.setAttribute( "keyAlias", OnejarMain.KEYSTORE_ALIAS );
         connector.setAttribute( "clientAuth", "false" );
 
-        final Properties tlsProperties = readConfiguredTlsProperties( onejarConfig );
         if ( tlsProperties != null )
         {
             for ( final String key : tlsProperties.stringPropertyNames() )
@@ -254,23 +254,32 @@ public class TomcatOnejarRunner
     }
 
 
-    void generatePwmKeystore( final OnejarConfig onejarConfig )
+    Properties executeOnejarHelper( final OnejarConfig onejarConfig )
             throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
     {
         try ( URLClassLoader classLoader = warClassLoaderFromConfig( onejarConfig ) )
         {
-            final Class pwmMainClass = classLoader.loadClass( "password.pwm.util.cli.MainClass" );
+            final Class pwmMainClass = classLoader.loadClass( "password.pwm.util.OnejarHelper" );
             final String keystoreFile = onejarConfig.getKeystoreFile().getAbsolutePath();
-            final Method mainMethod = pwmMainClass.getMethod( "main", String[].class );
+            final Method mainMethod = pwmMainClass.getMethod(
+                    "onejarHelper",
+                    String.class,
+                    String.class,
+                    String.class,
+                    String.class
+            );
+
             final String[] arguments = new String[] {
-                    "-applicationPath=" + onejarConfig.getApplicationPath().getAbsolutePath(),
-                    "ExportHttpsKeyStore",
+                    onejarConfig.getApplicationPath().getAbsolutePath(),
                     keystoreFile,
                     OnejarMain.KEYSTORE_ALIAS,
                     onejarConfig.getKeystorePass(),
             };
 
-            mainMethod.invoke( null, ( Object ) arguments );
+            final Object returnObjValue = mainMethod.invoke( null, arguments );
+            final Properties returnProps = ( Properties ) returnObjValue;
+            out( "completed read of tlsProperties " );
+            return returnProps;
         }
     }
 
@@ -313,22 +322,6 @@ public class TomcatOnejarRunner
         }
     }
 
-    Properties readConfiguredTlsProperties( final OnejarConfig onejarConfig )
-            throws Exception
-    {
-        out( "beginning read of tlsProperties " );
-        try ( URLClassLoader classLoader = warClassLoaderFromConfig( onejarConfig ) )
-        {
-            final Class pwmMainClass = classLoader.loadClass( "password.pwm.util.cli.commands.ExportHttpsTomcatConfigCommand" );
-            final Method readMethod = pwmMainClass.getMethod( "readAsProperties", String.class );
-            final String arguments = onejarConfig.getApplicationPath().getAbsolutePath();
-            final Object returnObjValue = readMethod.invoke( null, ( Object ) arguments );
-            final Properties returnProps = ( Properties ) returnObjValue;
-            out( "completed read of tlsProperties " );
-            return returnProps;
-        }
-    }
-
     URLClassLoader warClassLoaderFromConfig( final OnejarConfig onejarConfig )
             throws IOException
     {

+ 1 - 1
rest-test-service/pom.xml

@@ -12,7 +12,7 @@
     <artifactId>rest-test-service</artifactId>
     <packaging>war</packaging>
 
-    <name>PWM Password Self Service: REST Test Server</name>
+    <name>PWM Password Self Service: REST Test Server WAR</name>
 
     <properties>
         <project.root.basedir>${project.basedir}/..</project.root.basedir>

+ 120 - 0
server/src/main/java/password/pwm/util/OnejarHelper.java

@@ -0,0 +1,120 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2018 The PWM Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package password.pwm.util;
+
+import password.pwm.PwmApplication;
+import password.pwm.PwmApplicationMode;
+import password.pwm.PwmConstants;
+import password.pwm.PwmEnvironment;
+import password.pwm.config.Configuration;
+import password.pwm.config.PwmSetting;
+import password.pwm.config.stored.ConfigurationReader;
+import password.pwm.error.PwmUnrecoverableException;
+import password.pwm.util.cli.commands.ExportHttpsTomcatConfigCommand;
+import password.pwm.util.java.StringUtil;
+import password.pwm.util.secure.HttpsServerCertificateManager;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.util.Collections;
+import java.util.Properties;
+
+public class OnejarHelper
+{
+    /**
+     * Invoked (via reflection) by tomcatOneJar class in Onejar module.
+     * @param applicationPath application path containing configuration file.
+     * @return Properties with tomcat connector parameters.
+     * @throws PwmUnrecoverableException if problem loading config
+     */
+    public static Properties onejarHelper(
+            final String applicationPath,
+            final String keystorePath,
+            final String alias,
+            final String password
+    )
+            throws Exception
+    {
+        final PwmApplication pwmApplication = makePwmApplication( new File( applicationPath ) );
+        try
+        {
+            exportKeystore( pwmApplication, password, alias, new File( keystorePath ) );
+            return createProperties( pwmApplication.getConfig() );
+        }
+        finally
+        {
+            pwmApplication.shutdown();
+        }
+    }
+
+    private static Properties createProperties( final Configuration configuration )
+            throws Exception
+    {
+        final String sslProtocolSettingValue = ExportHttpsTomcatConfigCommand.TomcatConfigWriter.getTlsProtocolsValue( configuration );
+        final Properties newProps = new Properties();
+        newProps.setProperty( "sslEnabledProtocols",  sslProtocolSettingValue );
+        final String ciphers = configuration.readSettingAsString( PwmSetting.HTTPS_CIPHERS );
+        if ( !StringUtil.isEmpty( ciphers ) )
+        {
+            newProps.setProperty( "ciphers", ciphers );
+        }
+        return newProps;
+    }
+
+    private static void exportKeystore(
+            final PwmApplication pwmApplication,
+            final String password,
+            final String alias,
+            final File exportFile
+    )
+            throws Exception
+    {
+        final KeyStore keyStore = HttpsServerCertificateManager.keyStoreForApplication(
+                pwmApplication,
+                new PasswordData( password ),
+                alias );
+        try ( OutputStream outputStream = new FileOutputStream( exportFile ) )
+        {
+            keyStore.store( outputStream, password.toCharArray() );
+        }
+    }
+
+    private static PwmApplication makePwmApplication( final File applicationPath )
+            throws Exception
+    {
+        final File configFile = new File( applicationPath + File.separator + PwmConstants.DEFAULT_CONFIG_FILE_FILENAME );
+        final ConfigurationReader configReader = new ConfigurationReader( configFile );
+        final Configuration config = configReader.getConfiguration();
+        final PwmEnvironment pwmEnvironment = new PwmEnvironment.Builder( config, applicationPath )
+                .setApplicationMode( PwmApplicationMode.READ_ONLY )
+                .setConfigurationFile( configFile )
+                .setFlags( Collections.singleton( PwmEnvironment.ApplicationFlag.CommandLineInstance ) )
+                .createPwmEnvironment();
+        return new PwmApplication( pwmEnvironment );
+    }
+
+
+
+}

+ 1 - 0
server/src/main/java/password/pwm/util/cli/MainClass.java

@@ -346,6 +346,7 @@ public class MainClass
             if ( !commandExceuted )
             {
                 out( "unknown command '" + workingArgs.iterator().next() + "'" );
+                out( "use 'help' for command list" );
             }
         }
     }

+ 0 - 1
server/src/main/java/password/pwm/util/cli/commands/ExportHttpsKeyStoreCommand.java

@@ -55,7 +55,6 @@ public class ExportHttpsKeyStoreCommand extends AbstractCliCommand
         try ( FileOutputStream fos = new FileOutputStream( outputFile ) )
         {
             keyStore.store( fos, password.toCharArray() );
-            fos.close();
         }
 
         out( "successfully exported java keystore to " + outputFile.getAbsolutePath() );

+ 1 - 29
server/src/main/java/password/pwm/util/cli/commands/ExportHttpsTomcatConfigCommand.java

@@ -27,10 +27,7 @@ import password.pwm.PwmConstants;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.option.TLSVersion;
-import password.pwm.config.stored.ConfigurationReader;
-import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.util.cli.CliParameters;
-import password.pwm.util.java.StringUtil;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -41,7 +38,6 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Properties;
 import java.util.Set;
 
 public class ExportHttpsTomcatConfigCommand extends AbstractCliCommand
@@ -109,30 +105,6 @@ public class ExportHttpsTomcatConfigCommand extends AbstractCliCommand
         return cliParameters;
     }
 
-    /**
-     * Invoked (via reflection) by tomcatOneJar class in Onejar module.
-     * @param applicationPath application path containing configuration file.
-     * @return Properties with tomcat connector parameters.
-     * @throws PwmUnrecoverableException if problem loading config
-     */
-    public static Properties readAsProperties( final String applicationPath )
-            throws PwmUnrecoverableException
-    {
-        final File configFile = new File( applicationPath + File.separator + PwmConstants.DEFAULT_CONFIG_FILE_FILENAME );
-        final ConfigurationReader reader = new ConfigurationReader( configFile );
-        final Configuration configuration = reader.getConfiguration();
-        final String sslProtocolSettingValue = TomcatConfigWriter.getTlsProtocolsValue( configuration );
-        final Properties newProps = new Properties();
-        newProps.setProperty( "sslEnabledProtocols",  sslProtocolSettingValue );
-        final String ciphers = configuration.readSettingAsString( PwmSetting.HTTPS_CIPHERS );
-        if ( !StringUtil.isEmpty( ciphers ) )
-        {
-            newProps.setProperty( "ciphers", ciphers );
-        }
-        return newProps;
-    }
-
-
     public static class TomcatConfigWriter
     {
 
@@ -153,7 +125,7 @@ public class ExportHttpsTomcatConfigCommand extends AbstractCliCommand
             outputFile.write( fileContents.getBytes( PwmConstants.DEFAULT_CHARSET ) );
         }
 
-        private static String getTlsProtocolsValue( final Configuration configuration )
+        public static String getTlsProtocolsValue( final Configuration configuration )
         {
             final Set<TLSVersion> tlsVersions = configuration.readSettingAsOptionList( PwmSetting.HTTPS_PROTOCOLS, TLSVersion.class );
             final StringBuilder output = new StringBuilder();