Skip to content

Commit c0c1933

Browse files
committed
Add admin acls for history server
Change-Id: Idc5509c7ee24c6cf717e35c0bdaebf3384baa59f
1 parent e1b43dc commit c0c1933

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

core/src/main/scala/org/apache/spark/deploy/history/FsHistoryProvider.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,13 @@ private[history] class FsHistoryProvider(conf: SparkConf, clock: Clock)
253253
val uiAclsEnabled = conf.getBoolean("spark.history.ui.acls.enable", false)
254254
ui.getSecurityManager.setAcls(uiAclsEnabled)
255255
// make sure to set admin acls before view acls so they are properly picked up
256-
ui.getSecurityManager.setAdminAcls(appListener.adminAcls.getOrElse(""))
257-
ui.getSecurityManager.setViewAcls(attempt.sparkUser,
258-
appListener.viewAcls.getOrElse(""))
259-
ui.getSecurityManager.setAdminAclsGroups(appListener.adminAclsGroups.getOrElse(""))
256+
val adminAcls = conf.get("spark.history.ui.admin.acls", "") + "," +
257+
appListener.adminAcls.getOrElse("")
258+
ui.getSecurityManager.setAdminAcls(adminAcls)
259+
ui.getSecurityManager.setViewAcls(attempt.sparkUser, appListener.viewAcls.getOrElse(""))
260+
val adminAclsGroups = conf.get("spark.history.ui.admin.acls.groups", "") + "," +
261+
appListener.adminAclsGroups.getOrElse("")
262+
ui.getSecurityManager.setAdminAclsGroups(adminAclsGroups)
260263
ui.getSecurityManager.setViewAclsGroups(appListener.viewAclsGroups.getOrElse(""))
261264
Some(LoadedAppUI(ui, updateProbe(appId, attemptId, attempt.fileSize)))
262265
} else {

core/src/test/scala/org/apache/spark/deploy/history/FsHistoryProviderSuite.scala

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import org.apache.spark.{SparkConf, SparkFunSuite}
3939
import org.apache.spark.internal.Logging
4040
import org.apache.spark.io._
4141
import org.apache.spark.scheduler._
42+
import org.apache.spark.security.GroupMappingServiceProvider
4243
import org.apache.spark.util.{Clock, JsonProtocol, ManualClock, Utils}
4344

4445
class FsHistoryProviderSuite extends SparkFunSuite with BeforeAndAfter with Matchers with Logging {
@@ -474,6 +475,48 @@ class FsHistoryProviderSuite extends SparkFunSuite with BeforeAndAfter with Matc
474475
}
475476
}
476477

478+
479+
test("support history server ui admin acls") {
480+
val conf = createTestConf()
481+
.set("spark.history.ui.acls.enable", "true")
482+
.set("spark.history.ui.admin.acls", "user1,user2")
483+
.set("spark.history.ui.admin.acls.groups", "group1")
484+
.set("spark.user.groups.mapping", classOf[TestGroupsMappingProvider].getName)
485+
486+
val provider = new FsHistoryProvider(conf)
487+
488+
val log = newLogFile("app1", Some("attempt1"), inProgress = false)
489+
writeFile(log, true, None,
490+
SparkListenerApplicationStart("app1", Some("app1"), System.currentTimeMillis(),
491+
"test", Some("attempt1")),
492+
SparkListenerEnvironmentUpdate(Map(
493+
"Spark Properties" -> Seq(
494+
("spark.admin.acls", "user"),
495+
("spark.admin.acls.groups", "group")),
496+
"JVM Information" -> Seq.empty,
497+
"System Properties" -> Seq.empty,
498+
"Classpath Entries" -> Seq.empty
499+
)),
500+
SparkListenerApplicationEnd(System.currentTimeMillis()))
501+
502+
provider.checkForLogs()
503+
val appUi = provider.getAppUI("app1", Some("attempt1"))
504+
505+
assert (appUi.nonEmpty)
506+
val securityManager = appUi.get.ui.securityManager
507+
508+
// Test whether user has permission to access UI.
509+
securityManager.checkUIViewPermissions("user1") should be (true)
510+
securityManager.checkUIViewPermissions("user2") should be (true)
511+
securityManager.checkUIViewPermissions("user") should be (true)
512+
securityManager.checkUIViewPermissions("abc") should be (false)
513+
514+
// Test whether user with admin group has permission to access UI.
515+
securityManager.checkUIViewPermissions("user3") should be (true)
516+
securityManager.checkUIViewPermissions("user4") should be (true)
517+
securityManager.checkUIViewPermissions("user5") should be (false)
518+
}
519+
477520
/**
478521
* Asks the provider to check for logs and calls a function to perform checks on the updated
479522
* app list. Example:
@@ -532,3 +575,14 @@ class FsHistoryProviderSuite extends SparkFunSuite with BeforeAndAfter with Matc
532575
}
533576

534577
}
578+
579+
class TestGroupsMappingProvider extends GroupMappingServiceProvider {
580+
private val mappings = Map(
581+
"user3" -> "group1",
582+
"user4" -> "group1")
583+
584+
override def getGroups(username: String): Set[String] = {
585+
mappings.get(username).map(Set(_)).getOrElse(Set.empty)
586+
}
587+
}
588+

docs/monitoring.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,28 @@ The history server can be configured as follows:
169169
If disabled, no access control checks are made.
170170
</td>
171171
</tr>
172+
<tr>
173+
<td>spark.history.ui.admin.acls</td>
174+
<td>empty</td>
175+
<td>
176+
Comma separated list of users/administrators that have view access to all the Spark applications in
177+
history server. By default only the users permitted to view the application at run-time could
178+
access the related application history, with this, configured users/administrators could also
179+
have the permission to access it.
180+
Putting a "*" in the list means any user can have the privilege of admin.
181+
</td>
182+
</tr>
183+
<tr>
184+
<td>spark.history.ui.admin.acls.groups</td>
185+
<td>empty</td>
186+
<td>
187+
Comma separated list of groups that have view access to all the Spark applications in
188+
history server. By default only the groups permitted to view the application at run-time could
189+
access the related application history, with this, configured groups could also
190+
have the permission to access it.
191+
Putting a "*" in the list means any group can have the privilege of admin.
192+
</td>
193+
</tr>
172194
<tr>
173195
<td>spark.history.fs.cleaner.enabled</td>
174196
<td>false</td>

0 commit comments

Comments
 (0)