[ https://issues.apache.org/jira/browse/KAFKA-5690?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16616616#comment-16616616 ]
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") ---------------------------------------------------------------- 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: us...@infra.apache.org > 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)