Explorar o código

HUE-3039 [livy] Enable support for SSL

Erick Tryzelaar %!s(int64=10) %!d(string=hai) anos
pai
achega
01926a2

+ 6 - 0
apps/spark/java/conf/livy-defaults.conf.tmpl

@@ -3,6 +3,12 @@
 # defaults to development
 ## livy.environment = development
 
+# Use this keystore for the SSL certificate and key.
+## livy.keystore =
+
+# Specify the keystore password.
+## livy.keystore.password =
+
 # What host address to start the server on. Defaults to 0.0.0.0. If using the
 # `yarn` factory mode, this address must be accessible from the YARN nodes.
 ## livy.server.host = 0.0.0.0

+ 32 - 6
apps/spark/java/livy-core/src/main/scala/com/cloudera/hue/livy/WebServer.scala

@@ -22,26 +22,52 @@ import java.net.{InetAddress, InetSocketAddress}
 import javax.servlet.ServletContextListener
 
 import ch.qos.logback.access.jetty.RequestLogImpl
-import org.eclipse.jetty.server.{NetworkConnector, Server}
+import org.eclipse.jetty.server._
 import org.eclipse.jetty.server.handler.{HandlerCollection, RequestLogHandler}
 import org.eclipse.jetty.servlet.{ServletContextHandler, DefaultServlet}
+import org.eclipse.jetty.util.ssl.SslContextFactory
 import org.scalatra.servlet.AsyncSupport
 
 import scala.concurrent.ExecutionContext
 
-class WebServer(var host: String, var port: Int) extends Logging {
-  val address = new InetSocketAddress(host, port)
-  val server = new Server(address)
+object WebServer {
+  val KeystoreKey = "livy.keystore"
+  val KeystorePasswordKey = "livy.keystore.password"
+}
+
+class WebServer(livyConf: LivyConf, var host: String, var port: Int) extends Logging {
+  val server = new Server()
 
   server.setStopTimeout(1000)
   server.setStopAtShutdown(true)
 
+  val connector = livyConf.getOption(WebServer.KeystoreKey) match {
+    case None =>
+      new ServerConnector(server)
+
+    case Some(keystore) =>
+      val https = new HttpConfiguration()
+      https.addCustomizer(new SecureRequestCustomizer())
+
+      val sslContextFactory = new SslContextFactory()
+      sslContextFactory.setKeyStorePath(keystore)
+      livyConf.getOption(WebServer.KeystorePasswordKey).foreach(sslContextFactory.setKeyStorePassword)
+      livyConf.getOption(WebServer.KeystorePasswordKey).foreach(sslContextFactory.setKeyManagerPassword)
+
+      new ServerConnector(server,
+        new SslConnectionFactory(sslContextFactory, "http/1.1"),
+        new HttpConnectionFactory(https))
+  }
+
+  connector.setHost(host)
+  connector.setPort(port)
+
+  server.setConnectors(Array(connector))
+
   val context = new ServletContextHandler()
 
   context.setContextPath("/")
-
   context.addServlet(classOf[DefaultServlet], "/")
-
   context.setAttribute(AsyncSupport.ExecutionContextKey, ExecutionContext.global)
 
   val handlers = new HandlerCollection

+ 2 - 2
apps/spark/java/livy-repl/src/main/scala/com/cloudera/hue/livy/repl/Main.scala

@@ -25,7 +25,7 @@ import com.cloudera.hue.livy.repl.python.PythonInterpreter
 import com.cloudera.hue.livy.repl.scala.SparkInterpreter
 import com.cloudera.hue.livy.repl.sparkr.SparkRInterpreter
 import com.cloudera.hue.livy.sessions.Starting
-import com.cloudera.hue.livy.{Logging, WebServer}
+import com.cloudera.hue.livy.{LivyConf, Logging, WebServer}
 import dispatch._
 import org.json4s.jackson.Serialization.write
 import org.json4s.{DefaultFormats, Formats}
@@ -68,7 +68,7 @@ object Main extends Logging {
         sys.exit(1)
     }
 
-    val server = new WebServer(host, port)
+    val server = new WebServer(new LivyConf(), host, port)
 
     server.context.setResourceBase("src/main/com/cloudera/hue/livy/repl")
     server.context.addEventListener(new ScalatraListener)

+ 2 - 5
apps/spark/java/livy-server/src/main/scala/com/cloudera/hue/livy/server/Main.scala

@@ -48,7 +48,7 @@ object Main {
     testSparkHome(livyConf)
     testSparkSubmit(livyConf)
 
-    val server = new WebServer(host, port)
+    val server = new WebServer(livyConf, host, port)
 
     server.context.setResourceBase("src/main/com/cloudera/hue/livy/server")
     server.context.setInitParameter(ScalatraListener.LifeCycleKey, classOf[ScalatraBootstrap].getCanonicalName)
@@ -171,10 +171,7 @@ class ScalatraBootstrap
       context.mount(new BatchSessionServlet(batchManager), "/batches/*")
       context.mountMetricsAdminServlet("/")
 
-      context.setInitParameter(org.scalatra.EnvironmentKey, livyConf.get("livy.environment", "development"))
-      context.setInitParameter(ScalatraBase.HostNameKey, livyConf.get("livy.hostname"))
-
-
+      context.initParameters(org.scalatra.EnvironmentKey) = livyConf.get("livy.environment", "development")
     } catch {
       case e: Throwable =>
         println(f"Exception thrown when initializing server: $e")