[
https://issues.apache.org/jira/browse/KAFKA-5690?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16617784#comment-16617784
]
ASF GitHub Bot commented on KAFKA-5690:
---------------------------------------
lindong28 closed pull request #5633: KAFKA-5690: Add support to list ACLs for a
given principal (KIP-357)
URL: https://github.com/apache/kafka/pull/5633
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/core/src/main/scala/kafka/admin/AclCommand.scala
b/core/src/main/scala/kafka/admin/AclCommand.scala
index c2dda33d5ab..ad375d20572 100644
--- a/core/src/main/scala/kafka/admin/AclCommand.scala
+++ b/core/src/main/scala/kafka/admin/AclCommand.scala
@@ -138,10 +138,22 @@ object AclCommand extends Logging {
def listAcls(): Unit = {
withAdminClient(opts) { adminClient =>
val filters = getResourceFilter(opts, dieIfNoResourceFound = false)
+ val listPrincipals = getPrincipals(opts, opts.listPrincipalsOpt)
val resourceToAcls = getAcls(adminClient, filters)
- for ((resource, acls) <- resourceToAcls)
- println(s"Current ACLs for resource `$resource`: $Newline
${acls.map("\t" + _).mkString(Newline)} $Newline")
+ if (listPrincipals.isEmpty) {
+ for ((resource, acls) <- resourceToAcls)
+ println(s"Current ACLs for resource `$resource`: $Newline
${acls.map("\t" + _).mkString(Newline)} $Newline")
+ } else {
+ listPrincipals.foreach(principal => {
+ println(s"ACLs for principal `$principal`")
+ val filteredResourceToAcls = resourceToAcls.mapValues(acls =>
+ acls.filter(acl =>
principal.toString.equals(acl.principal))).filter(entry => entry._2.nonEmpty)
+
+ for ((resource, acls) <- filteredResourceToAcls)
+ println(s"Current ACLs for resource `$resource`: $Newline
${acls.map("\t" + _).mkString(Newline)} $Newline")
+ })
+ }
}
}
@@ -237,13 +249,20 @@ object AclCommand extends Logging {
def listAcls(): Unit = {
withAuthorizer() { authorizer =>
val filters = getResourceFilter(opts, dieIfNoResourceFound = false)
+ val listPrincipals = getPrincipals(opts, opts.listPrincipalsOpt)
- val resourceToAcls: Iterable[(Resource, Set[Acl])] =
- if (filters.isEmpty) authorizer.getAcls()
- else filters.flatMap(filter => getAcls(authorizer, filter))
-
- for ((resource, acls) <- resourceToAcls)
- println(s"Current ACLs for resource `$resource`: $Newline
${acls.map("\t" + _).mkString(Newline)} $Newline")
+ if (listPrincipals.isEmpty) {
+ val resourceToAcls = getFilteredResourceToAcls(authorizer, filters)
+ for ((resource, acls) <- resourceToAcls)
+ println(s"Current ACLs for resource `$resource`: $Newline
${acls.map("\t" + _).mkString(Newline)} $Newline")
+ } else {
+ listPrincipals.foreach(principal => {
+ println(s"ACLs for principal `$principal`")
+ val resourceToAcls = getFilteredResourceToAcls(authorizer,
filters, Some(principal))
+ for ((resource, acls) <- resourceToAcls)
+ println(s"Current ACLs for resource `$resource`: $Newline
${acls.map("\t" + _).mkString(Newline)} $Newline")
+ })
+ }
}
}
@@ -256,9 +275,23 @@ object AclCommand extends Logging {
)
}
- private def getAcls(authorizer: Authorizer, filter:
ResourcePatternFilter): Map[Resource, Set[Acl]] =
- authorizer.getAcls()
- .filter { case (resource, acl) => filter.matches(resource.toPattern) }
+ private def getFilteredResourceToAcls(authorizer: Authorizer, filters:
Set[ResourcePatternFilter],
+ listPrincipal:
Option[KafkaPrincipal] = None): Iterable[(Resource, Set[Acl])] = {
+ if (filters.isEmpty)
+ if (listPrincipal.isEmpty)
+ authorizer.getAcls()
+ else
+ authorizer.getAcls(listPrincipal.get)
+ else filters.flatMap(filter => getAcls(authorizer, filter,
listPrincipal))
+ }
+
+ private def getAcls(authorizer: Authorizer, filter: ResourcePatternFilter,
+ listPrincipal: Option[KafkaPrincipal] = None):
Map[Resource, Set[Acl]] =
+ if (listPrincipal.isEmpty)
+ authorizer.getAcls().filter { case (resource, acl) =>
filter.matches(resource.toPattern) }
+ else
+ authorizer.getAcls(listPrincipal.get).filter { case (resource, acl) =>
filter.matches(resource.toPattern) }
+
}
private def getResourceToAcls(opts: AclCommandOptions): Map[Resource,
Set[Acl]] = {
@@ -521,6 +554,12 @@ object AclCommand extends Logging {
.describedAs("deny-principal")
.ofType(classOf[String])
+ val listPrincipalsOpt = parser.accepts("principal", "List ACLs for the
specified principal. principal is in principalType:name format." +
+ " Note that principalType must be supported by the Authorizer being
used. Multiple --principal option can be passed.")
+ .withOptionalArg()
+ .describedAs("principal")
+ .ofType(classOf[String])
+
val allowHostsOpt = parser.accepts("allow-host", "Host from which
principals listed in --allow-principal will have access. " +
"If you have specified --allow-principal then the default for this
option will be set to * which allows access from all hosts.")
.withRequiredArg
@@ -568,6 +607,9 @@ object AclCommand extends Logging {
CommandLineUtils.checkInvalidArgs(parser, options, producerOpt,
Set(operationsOpt, denyPrincipalsOpt, denyHostsOpt))
CommandLineUtils.checkInvalidArgs(parser, options, consumerOpt,
Set(operationsOpt, denyPrincipalsOpt, denyHostsOpt))
+ if (options.has(listPrincipalsOpt) && !options.has(listOpt))
+ CommandLineUtils.printUsageAndDie(parser, "The --principal option is
only available if --list is set")
+
if (options.has(producerOpt) && !options.has(topicOpt))
CommandLineUtils.printUsageAndDie(parser, "With --producer you must
specify a --topic")
diff --git a/docs/security.html b/docs/security.html
index e856a7e1686..924c1bf6c40 100644
--- a/docs/security.html
+++ b/docs/security.html
@@ -1129,6 +1129,12 @@ <h4><a id="security_authz_cli"
href="#security_authz_cli">Command Line Interface
<td></td>
<td>Principal</td>
</tr>
+ <tr>
+ <td>--principal</td>
+ <td>Principal is in PrincipalType:name format that will be used
along with --list option. This will list the ACLs for the specified principal.
<br>You can specify multiple --principal in a single command.</td>
+ <td></td>
+ <td>Principal</td>
+ </tr>
<tr>
<td>--allow-host</td>
<td>IP address from which principals listed in --allow-principal
will have access.</td>
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> kafka-acls command should be able to list per principal
> -------------------------------------------------------
>
> Key: KAFKA-5690
> URL: https://issues.apache.org/jira/browse/KAFKA-5690
> Project: Kafka
> Issue Type: Bug
> Components: core
> Affects Versions: 0.10.2.0, 0.11.0.0
> Reporter: Koelli Mungee
> Assignee: Manikumar
> Priority: Major
> Fix For: 2.1.0
>
>
> Currently the `kafka-acls` command has a `--list` option that can list per
> resource which is --topic <topic> or --group <group> or --cluster. In order
> to look at the ACLs for a particular principal the user needs to iterate
> through the entire list to figure out what privileges a particular principal
> has been granted. An option to list the ACL per principal would simplify this
> process.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)