Skip to content

Commit

Permalink
[KYUUBI apache#4376] Support to config the kyuubi service administrat…
Browse files Browse the repository at this point in the history
…or with kyuubi conf

### _Why are the changes needed?_

Close apache#4376

### _How was this patch tested?_
- [x] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests) locally before make a pull request

Closes apache#4405 from lightning-L/kyuubi-4376.

Closes apache#4376

1a01a75 [Tianlin Liao] rename and refactor
7324cab [Tianlin Liao] [KYUUBI apache#4376] Support to config the kyuubi service administrator with kyuubi conf

Authored-by: Tianlin Liao <tiliao@ebay.com>
Signed-off-by: fwang12 <fwang12@ebay.com>
  • Loading branch information
lightning-L authored and turboFei committed Feb 26, 2023
1 parent 43309b8 commit 59c1875
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/deployment/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ You can configure the Kyuubi properties in `$KYUUBI_HOME/conf/kyuubi-defaults.co

| Key | Default | Meaning | Type | Since |
|----------------------------------------------------------|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-------|
| kyuubi.server.administrators || Comma-separated list of Kyuubi service administrators. We use this config to grant admin permission to any service accounts. | seq | 1.8.0 |
| kyuubi.server.info.provider | ENGINE | The server information provider name, some clients may rely on this information to check the server compatibilities and functionalities. <li>SERVER: Return Kyuubi server information.</li> <li>ENGINE: Return Kyuubi engine information.</li> | string | 1.6.1 |
| kyuubi.server.limit.batch.connections.per.ipaddress | &lt;undefined&gt; | Maximum kyuubi server batch connections per ipaddress. Any user exceeding this limit will not be allowed to connect. | int | 1.7.0 |
| kyuubi.server.limit.batch.connections.per.user | &lt;undefined&gt; | Maximum kyuubi server batch connections per user. Any user exceeding this limit will not be allowed to connect. | int | 1.7.0 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2429,6 +2429,16 @@ object KyuubiConf {
.timeConf
.createWithDefaultString("PT30M")

val SERVER_ADMINISTRATORS: ConfigEntry[Seq[String]] =
buildConf("kyuubi.server.administrators")
.doc("Comma-separated list of Kyuubi service administrators. " +
"We use this config to grant admin permission to any service accounts.")
.version("1.8.0")
.serverOnly
.stringConf
.toSequence()
.createWithDefault(Nil)

val OPERATION_SPARK_LISTENER_ENABLED: ConfigEntry[Boolean] =
buildConf("kyuubi.operation.spark.listener.enabled")
.doc("When set to true, Spark engine registers an SQLOperationListener before executing " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ import org.apache.kyuubi.server.api.ApiRequestContext
@Tag(name = "Admin")
@Produces(Array(MediaType.APPLICATION_JSON))
private[v1] class AdminResource extends ApiRequestContext with Logging {
private lazy val administrator = Utils.currentUser
private lazy val administrators = fe.getConf.get(KyuubiConf.SERVER_ADMINISTRATORS).toSet +
Utils.currentUser

@ApiResponse(
responseCode = "200",
Expand All @@ -54,7 +55,7 @@ private[v1] class AdminResource extends ApiRequestContext with Logging {
val userName = fe.getSessionUser(Map.empty[String, String])
val ipAddress = fe.getIpAddress
info(s"Receive refresh Kyuubi server hadoop conf request from $userName/$ipAddress")
if (!userName.equals(administrator)) {
if (!isAdministrator(userName)) {
throw new NotAllowedException(
s"$userName is not allowed to refresh the Kyuubi server hadoop conf")
}
Expand All @@ -73,7 +74,7 @@ private[v1] class AdminResource extends ApiRequestContext with Logging {
val userName = fe.getSessionUser(Map.empty[String, String])
val ipAddress = fe.getIpAddress
info(s"Receive refresh user defaults conf request from $userName/$ipAddress")
if (!userName.equals(administrator)) {
if (!isAdministrator(userName)) {
throw new NotAllowedException(
s"$userName is not allowed to refresh the user defaults conf")
}
Expand All @@ -92,7 +93,7 @@ private[v1] class AdminResource extends ApiRequestContext with Logging {
val userName = fe.getSessionUser(Map.empty[String, String])
val ipAddress = fe.getIpAddress
info(s"Receive refresh unlimited users request from $userName/$ipAddress")
if (!userName.equals(administrator)) {
if (!isAdministrator(userName)) {
throw new NotAllowedException(
s"$userName is not allowed to refresh the unlimited users")
}
Expand Down Expand Up @@ -212,4 +213,8 @@ private[v1] class AdminResource extends ApiRequestContext with Logging {
engine.getUser,
engine.getSubdomain)
}

private def isAdministrator(userName: String): Boolean = {
administrators.contains(userName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class AdminResourceSuite extends KyuubiFunSuite with RestFrontendTestHelper {

private val engineMgr = new KyuubiApplicationManager()

override protected lazy val conf: KyuubiConf = KyuubiConf()
.set(KyuubiConf.SERVER_ADMINISTRATORS, Seq("admin001"))

override def beforeAll(): Unit = {
super.beforeAll()
engineMgr.initialize(KyuubiConf())
Expand Down Expand Up @@ -64,6 +67,24 @@ class AdminResourceSuite extends KyuubiFunSuite with RestFrontendTestHelper {
.header(AUTHORIZATION_HEADER, s"BASIC $encodeAuthorization")
.post(null)
assert(200 == response.getStatus)

val admin001AuthHeader = new String(
Base64.getEncoder.encode("admin001".getBytes()),
"UTF-8")
response = webTarget.path("api/v1/admin/refresh/hadoop_conf")
.request()
.header(AUTHORIZATION_HEADER, s"BASIC $admin001AuthHeader")
.post(null)
assert(200 == response.getStatus)

val admin002AuthHeader = new String(
Base64.getEncoder.encode("admin002".getBytes()),
"UTF-8")
response = webTarget.path("api/v1/admin/refresh/hadoop_conf")
.request()
.header(AUTHORIZATION_HEADER, s"BASIC $admin002AuthHeader")
.post(null)
assert(405 == response.getStatus)
}

test("refresh user defaults config of the kyuubi server") {
Expand Down

0 comments on commit 59c1875

Please sign in to comment.