From 97818590b49b548f6aeeecab16e9c1b54f10a0a5 Mon Sep 17 00:00:00 2001 From: yangguo Date: Thu, 24 Jun 2021 11:57:01 -0700 Subject: [PATCH 1/3] update remove acls --- .../kafka/admin/AzPubSubAclCommand.scala | 61 ++++++++++++++++++- .../main/scala/kafka/admin/AclCommand.scala | 14 ++--- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala b/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala index ed9c01a1e3fc5..510fcb9c164e2 100644 --- a/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala +++ b/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala @@ -1,7 +1,8 @@ package com.microsoft.azpubsub.kafka.admin import kafka.admin.AclCommand -import kafka.admin.AclCommand.{AclCommandOptions, AdminClientService} +import kafka.admin.AclCommand.{AclCommandOptions, AdminClientService, confirmAction, getPrincipals, getResourceFilter, getResourceFilterToAcls} import kafka.utils.{CommandLineUtils, Exit, Json, Logging} +import org.apache.kafka.clients.admin.Admin import org.apache.kafka.common.acl.{AccessControlEntry, AclOperation, AclPermissionType} import org.apache.kafka.common.resource.{ResourcePattern, ResourcePatternFilter, ResourceType} import org.apache.kafka.common.security.auth.KafkaPrincipal @@ -44,6 +45,34 @@ object AzPubSubAclCommand extends Logging { class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminClientService(opts) { + private val Newline = scala.util.Properties.lineSeparator + + override def removeAcls(): Unit = { + withAdminClient(opts) { adminClient => + val filteredAclOperations = getFilteredAclOperations(adminClient, opts) + val producerAclOperations = GetProducerAclOperations() + val consumerAclOperations = GetConsumerAclOperations() + + val filterToAcl = getResourceFilterToAcls(opts) + + for ((filter, acls) <- filterToAcl) { + if (acls.isEmpty) { + if (confirmAction(opts, s"Are you sure you want to delete all ACLs for resource filter `$filter`? (y/n)")) + removeAcls(adminClient, acls, filter) + } else { + if ((opts.options.has(opts.producerOpt) && consumerAclOperations.subsetOf(filteredAclOperations)) + || (opts.options.has(opts.consumerOpt) && producerAclOperations.subsetOf(filteredAclOperations))) + removeAclWithDescribeOperation(acls) + if (confirmAction(opts, s"Are you sure you want to remove ACLs: $Newline ${acls.map("\t" + _).mkString(Newline)} $Newline from resource filter `$filter`? (y/n)")) { + removeAcls(adminClient, acls, filter) + } + } + } + + listAcls() + } + } + override def printAcls(filters: Set[ResourcePatternFilter], listPrincipals: Set[KafkaPrincipal], resourceToAcls: Map[ResourcePattern, Set[AccessControlEntry]]): Unit = { if (!opts.options.has(opts.outputAsProducerConsumerOpt)) { super.printAcls(filters, listPrincipals, resourceToAcls) @@ -170,6 +199,36 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC }) return producerConsumerGroupAclMap } + + def removeAclWithDescribeOperation(acls: Set[AccessControlEntry]): Set[AccessControlEntry] ={ + val updatedAcls = mutable.Set[AccessControlEntry]() + updatedAcls += acls + acls.foreach(acl => { + if (acl.operation() == AclOperation.DESCRIBE) + updatedAcls -= acl + }) + updatedAcls.toSet + } + + def getFilteredAclOperations(adminClient: Admin, opts: AzPubSubAclCommandOptions): Set[AclOperation] ={ + val aclOperations = mutable.Set[AclOperation]() + + val filters = getResourceFilter(opts, dieIfNoResourceFound = false) + val listPrincipals = getPrincipals(opts, opts.listPrincipalsOpt) + val resourceToAcls = getAcls(adminClient, filters) + + if (!listPrincipals.isEmpty) { + listPrincipals.foreach(principal => { + val filteredResourceToAcls = resourceToAcls.mapValues(acls => + acls.filter(acl => principal.toString.equals(acl.principal) && acl.host() == "*" && acl.permissionType() == AclPermissionType.ALLOW)).filter(entry => entry._2.nonEmpty) + for ((_, filteredAcls) <- filteredResourceToAcls) { + filteredAcls.foreach(x => aclOperations.add(x.operation())) + } + }) + } + + aclOperations.toSet + } } class AzPubSubAclCommandOptions (args: Array[String]) extends AclCommandOptions(args.filterNot(x => (x == "--pc"))){ diff --git a/core/src/main/scala/kafka/admin/AclCommand.scala b/core/src/main/scala/kafka/admin/AclCommand.scala index 79ab6d1677a19..0aed726d15419 100644 --- a/core/src/main/scala/kafka/admin/AclCommand.scala +++ b/core/src/main/scala/kafka/admin/AclCommand.scala @@ -96,7 +96,7 @@ object AclCommand extends Logging { class AdminClientService(val opts: AclCommandOptions) extends AclCommandService with Logging { - private def withAdminClient(opts: AclCommandOptions)(f: Admin => Unit): Unit = { + protected def withAdminClient(opts: AclCommandOptions)(f: Admin => Unit): Unit = { val props = if (opts.options.has(opts.commandConfigOpt)) Utils.loadProps(opts.options.valueOf(opts.commandConfigOpt)) else @@ -167,7 +167,7 @@ object AclCommand extends Logging { } } - private def removeAcls(adminClient: Admin, acls: Set[AccessControlEntry], filter: ResourcePatternFilter): Unit = { + protected def removeAcls(adminClient: Admin, acls: Set[AccessControlEntry], filter: ResourcePatternFilter): Unit = { if (acls.isEmpty) adminClient.deleteAcls(List(new AclBindingFilter(filter, AccessControlEntryFilter.ANY)).asJava).all().get() else { @@ -176,7 +176,7 @@ object AclCommand extends Logging { } } - private def getAcls(adminClient: Admin, filters: Set[ResourcePatternFilter]): Map[ResourcePattern, Set[AccessControlEntry]] = { + protected def getAcls(adminClient: Admin, filters: Set[ResourcePatternFilter]): Map[ResourcePattern, Set[AccessControlEntry]] = { val aclBindings = if (filters.isEmpty) adminClient.describeAcls(AclBindingFilter.ANY).values().get().asScala.toList else { @@ -424,7 +424,7 @@ object AclCommand extends Logging { resourceToAcl } - private def getResourceFilterToAcls(opts: AclCommandOptions): Map[ResourcePatternFilter, Set[AccessControlEntry]] = { + def getResourceFilterToAcls(opts: AclCommandOptions): Map[ResourcePatternFilter, Set[AccessControlEntry]] = { var resourceToAcls = Map.empty[ResourcePatternFilter, Set[AccessControlEntry]] //if none of the --producer or --consumer options are specified , just construct ACLs from CLI options. @@ -526,14 +526,14 @@ object AclCommand extends Logging { Set.empty[String] } - private def getPrincipals(opts: AclCommandOptions, principalOptionSpec: ArgumentAcceptingOptionSpec[String]): Set[KafkaPrincipal] = { + def getPrincipals(opts: AclCommandOptions, principalOptionSpec: ArgumentAcceptingOptionSpec[String]): Set[KafkaPrincipal] = { if (opts.options.has(principalOptionSpec)) opts.options.valuesOf(principalOptionSpec).asScala.map(s => JSecurityUtils.parseKafkaPrincipal(s.trim)).toSet else Set.empty[KafkaPrincipal] } - private def getResourceFilter(opts: AclCommandOptions, dieIfNoResourceFound: Boolean = true): Set[ResourcePatternFilter] = { + def getResourceFilter(opts: AclCommandOptions, dieIfNoResourceFound: Boolean = true): Set[ResourcePatternFilter] = { val patternType: PatternType = opts.options.valueOf(opts.resourcePatternType) var resourceFilters = Set.empty[ResourcePatternFilter] @@ -559,7 +559,7 @@ object AclCommand extends Logging { resourceFilters } - private def confirmAction(opts: AclCommandOptions, msg: String): Boolean = { + def confirmAction(opts: AclCommandOptions, msg: String): Boolean = { if (opts.options.has(opts.forceOpt)) return true println(msg) From 3d85d4592157329b4a8eba0ee92df3917307373a Mon Sep 17 00:00:00 2001 From: yangguo Date: Tue, 29 Jun 2021 21:56:43 -0700 Subject: [PATCH 2/3] fix the bug of deleting shared operation --- .../kafka/admin/AzPubSubAclCommand.scala | 115 +++++++++--------- 1 file changed, 60 insertions(+), 55 deletions(-) diff --git a/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala b/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala index 510fcb9c164e2..de1105fc2ca8f 100644 --- a/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala +++ b/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala @@ -1,8 +1,7 @@ package com.microsoft.azpubsub.kafka.admin import kafka.admin.AclCommand -import kafka.admin.AclCommand.{AclCommandOptions, AdminClientService, confirmAction, getPrincipals, getResourceFilter, getResourceFilterToAcls} +import kafka.admin.AclCommand.{AclCommandOptions, AdminClientService, confirmAction, getResourceFilter, getResourceFilterToAcls} import kafka.utils.{CommandLineUtils, Exit, Json, Logging} -import org.apache.kafka.clients.admin.Admin import org.apache.kafka.common.acl.{AccessControlEntry, AclOperation, AclPermissionType} import org.apache.kafka.common.resource.{ResourcePattern, ResourcePatternFilter, ResourceType} import org.apache.kafka.common.security.auth.KafkaPrincipal @@ -49,22 +48,20 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC override def removeAcls(): Unit = { withAdminClient(opts) { adminClient => - val filteredAclOperations = getFilteredAclOperations(adminClient, opts) - val producerAclOperations = GetProducerAclOperations() - val consumerAclOperations = GetConsumerAclOperations() + val filters = getResourceFilter(opts, dieIfNoResourceFound = false) + val resourceToAcls = getAcls(adminClient, filters) val filterToAcl = getResourceFilterToAcls(opts) for ((filter, acls) <- filterToAcl) { + val filteredPrincipalAclOperationsMap = getPrincipalAclOperationsMap(resourceToAcls, filter) if (acls.isEmpty) { if (confirmAction(opts, s"Are you sure you want to delete all ACLs for resource filter `$filter`? (y/n)")) removeAcls(adminClient, acls, filter) } else { - if ((opts.options.has(opts.producerOpt) && consumerAclOperations.subsetOf(filteredAclOperations)) - || (opts.options.has(opts.consumerOpt) && producerAclOperations.subsetOf(filteredAclOperations))) - removeAclWithDescribeOperation(acls) - if (confirmAction(opts, s"Are you sure you want to remove ACLs: $Newline ${acls.map("\t" + _).mkString(Newline)} $Newline from resource filter `$filter`? (y/n)")) { - removeAcls(adminClient, acls, filter) + val updatedAcls = removeAclWithDescribeOperation(opts, acls, filteredPrincipalAclOperationsMap) + if (confirmAction(opts, s"Are you sure you want to remove ACLs: $Newline ${updatedAcls.map("\t" + _).mkString(Newline)} $Newline from resource filter `$filter`? (y/n)")) { + removeAcls(adminClient, updatedAcls, filter) } } } @@ -86,7 +83,7 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC val allPrincipalsFilteredResourceToAcls = resourceToAcls.mapValues(acls => acls.filterNot(acl => listPrincipals.forall( principal => !principal.toString.equals(acl.principal)))).filter(entry => entry._2.nonEmpty) - var producerConsumerAclMap = aclToProducerConsumerMapping(allPrincipalsFilteredResourceToAcls) + val producerConsumerAclMap = aclToProducerConsumerMapping(allPrincipalsFilteredResourceToAcls) outputAsJson(producerConsumerAclMap) } } @@ -109,9 +106,9 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC } def GetProducerAclOperations(): Set[AclOperation] = { - var dummyArgs = Array[String]("--bootstrap-server", "localhost:9092", "--add", "--allow-principal", "User:Bob", "--producer", "--topic", "Test-topic") - var dummyOpt = new AclCommandOptions(dummyArgs) - var resourceMap = AclCommand.getProducerResourceFilterToAcls(dummyOpt) + val dummyArgs = Array[String]("--bootstrap-server", "localhost:9092", "--add", "--allow-principal", "User:Bob", "--producer", "--topic", "Test-topic") + val dummyOpt = new AclCommandOptions(dummyArgs) + val resourceMap = AclCommand.getProducerResourceFilterToAcls(dummyOpt) for ((key, value) <- resourceMap) { if (key.resourceType() == ResourceType.TOPIC) { var aclOperationList = Set[AclOperation]() @@ -119,13 +116,13 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC return aclOperationList } } - return Set[AclOperation]() + Set[AclOperation]() } def GetConsumerAclOperations(): Set[AclOperation] = { - var dummyArgs = Array[String]("--bootstrap-server", "localhost:9092", "--add", "--allow-principal", "User:Bob", "--consumer", "--topic", "Test-topic", "--group", "Test-group") - var dummyOpt = new AclCommandOptions(dummyArgs) - var resourceMap = AclCommand.getConsumerResourceFilterToAcls(dummyOpt) + val dummyArgs = Array[String]("--bootstrap-server", "localhost:9092", "--add", "--allow-principal", "User:Bob", "--consumer", "--topic", "Test-topic", "--group", "Test-group") + val dummyOpt = new AclCommandOptions(dummyArgs) + val resourceMap = AclCommand.getConsumerResourceFilterToAcls(dummyOpt) for ((key, value) <- resourceMap) { if (key.resourceType() == ResourceType.TOPIC) { var aclOperationList = Set[AclOperation]() @@ -133,13 +130,13 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC return aclOperationList } } - return Set[AclOperation]() + Set[AclOperation]() } def GetGroupAclOperations(): Set[AclOperation] = { - var dummyArgs = Array[String]("--bootstrap-server", "localhost:9092", "--add", "--allow-principal", "User:Bob", "--consumer", "--topic", "Test-topic", "--group", "Test-group") - var dummyOpt = new AclCommandOptions(dummyArgs) - var resourceMap = AclCommand.getConsumerResourceFilterToAcls(dummyOpt) + val dummyArgs = Array[String]("--bootstrap-server", "localhost:9092", "--add", "--allow-principal", "User:Bob", "--consumer", "--topic", "Test-topic", "--group", "Test-group") + val dummyOpt = new AclCommandOptions(dummyArgs) + val resourceMap = AclCommand.getConsumerResourceFilterToAcls(dummyOpt) for ((key, value) <- resourceMap) { if (key.resourceType() == ResourceType.GROUP) { var aclOperationList = Set[AclOperation]() @@ -147,14 +144,14 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC return aclOperationList } } - return Set[AclOperation]() + Set[AclOperation]() } def aclToProducerConsumerMapping(resourceToAcls:Map[ResourcePattern,Set[AccessControlEntry]]):mutable.Map[ResourcePattern,mutable.Set[AzPubSubAccessControlEntry]] = { var producerConsumerGroupAclMap = mutable.Map[ResourcePattern, mutable.Set[AzPubSubAccessControlEntry]]() - var producerAclOperations = GetProducerAclOperations() - var consumerAclOperations = GetConsumerAclOperations() - var groupAclOperations = GetGroupAclOperations() + val producerAclOperations = GetProducerAclOperations() + val consumerAclOperations = GetConsumerAclOperations() + val groupAclOperations = GetGroupAclOperations() resourceToAcls.foreach(resource => { producerConsumerGroupAclMap += (resource._1 -> mutable.Set[AzPubSubAccessControlEntry]()) @@ -169,65 +166,73 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC }) principalAclMap.foreach { case (principal, acls) => { var strayAcls = acls - var filteredAclOperations = mutable.Set[AclOperation]() - var filteredAcls = acls.filter(x => (x.host() == "*" && x.permissionType() == AclPermissionType.ALLOW)) + val filteredAclOperations = mutable.Set[AclOperation]() + val filteredAcls = acls.filter(x => (x.host() == "*" && x.permissionType() == AclPermissionType.ALLOW)) filteredAcls.foreach(x => filteredAclOperations.add(x.operation())) if (resource._1.resourceType() == ResourceType.TOPIC) { if (producerAclOperations.subsetOf(filteredAclOperations)) { strayAcls = strayAcls.filterNot(x => (x.host() == "*" && x.permissionType() == AclPermissionType.ALLOW && producerAclOperations.contains(x.operation()))) - var modifiedAcl = new AzPubSubAccessControlEntry(principal, "*", AclOperation.ANY, AclPermissionType.ALLOW, "PRODUCER") + val modifiedAcl = new AzPubSubAccessControlEntry(principal, "*", AclOperation.ANY, AclPermissionType.ALLOW, "PRODUCER") producerConsumerGroupAclMap(resource._1).add(modifiedAcl) } if (consumerAclOperations.subsetOf(filteredAclOperations)) { strayAcls = strayAcls.filterNot(x => (x.host() == "*" && x.permissionType() == AclPermissionType.ALLOW && consumerAclOperations.contains(x.operation()))) - var modifiedAcl = new AzPubSubAccessControlEntry(principal, "*", AclOperation.ANY, AclPermissionType.ALLOW, "CONSUMER") + val modifiedAcl = new AzPubSubAccessControlEntry(principal, "*", AclOperation.ANY, AclPermissionType.ALLOW, "CONSUMER") producerConsumerGroupAclMap(resource._1).add(modifiedAcl) } } else if (resource._1.resourceType() == ResourceType.GROUP) { if (groupAclOperations.subsetOf(filteredAclOperations)) { strayAcls = strayAcls.filterNot(x => (x.host() == "*" && x.permissionType() == AclPermissionType.ALLOW && groupAclOperations.contains(x.operation()))) - var modifiedAcl = new AzPubSubAccessControlEntry(principal, "*", AclOperation.ANY, AclPermissionType.ALLOW, "GROUP") + val modifiedAcl = new AzPubSubAccessControlEntry(principal, "*", AclOperation.ANY, AclPermissionType.ALLOW, "GROUP") producerConsumerGroupAclMap(resource._1).add(modifiedAcl) } } strayAcls.foreach(acl => { - var modifiedAcl = new AzPubSubAccessControlEntry(principal, acl.host(), acl.operation(), acl.permissionType(), "NONE") + val modifiedAcl = new AzPubSubAccessControlEntry(principal, acl.host(), acl.operation(), acl.permissionType(), "NONE") producerConsumerGroupAclMap(resource._1).add(modifiedAcl) }) }} }) - return producerConsumerGroupAclMap + producerConsumerGroupAclMap } - def removeAclWithDescribeOperation(acls: Set[AccessControlEntry]): Set[AccessControlEntry] ={ - val updatedAcls = mutable.Set[AccessControlEntry]() - updatedAcls += acls + def removeAclWithDescribeOperation(opt: AzPubSubAclCommandOptions, acls: Set[AccessControlEntry], principalAclOperationsMap: Map[String, Set[AclOperation]]): Set[AccessControlEntry] ={ + val producerAclOperations = GetProducerAclOperations() + val consumerAclOperations = GetConsumerAclOperations() + + var updatedAcls = acls acls.foreach(acl => { - if (acl.operation() == AclOperation.DESCRIBE) - updatedAcls -= acl + if (acl.operation() == AclOperation.DESCRIBE) { + if ((opt.options.has(opt.producerOpt) && consumerAclOperations.subsetOf(principalAclOperationsMap(acl.principal()))) + || (opt.options.has(opt.consumerOpt) && producerAclOperations.subsetOf(principalAclOperationsMap(acl.principal())))) { + updatedAcls -= acl + } + } }) - updatedAcls.toSet - } - def getFilteredAclOperations(adminClient: Admin, opts: AzPubSubAclCommandOptions): Set[AclOperation] ={ - val aclOperations = mutable.Set[AclOperation]() + updatedAcls + } - val filters = getResourceFilter(opts, dieIfNoResourceFound = false) - val listPrincipals = getPrincipals(opts, opts.listPrincipalsOpt) - val resourceToAcls = getAcls(adminClient, filters) + def getPrincipalAclOperationsMap(resourceToAcls: Map[ResourcePattern, Set[AccessControlEntry]], filter: ResourcePatternFilter): Map[String, Set[AclOperation]] ={ + val principalAclOperationsMap = mutable.Map[String, Set[AclOperation]]() - if (!listPrincipals.isEmpty) { - listPrincipals.foreach(principal => { - val filteredResourceToAcls = resourceToAcls.mapValues(acls => - acls.filter(acl => principal.toString.equals(acl.principal) && acl.host() == "*" && acl.permissionType() == AclPermissionType.ALLOW)).filter(entry => entry._2.nonEmpty) - for ((_, filteredAcls) <- filteredResourceToAcls) { - filteredAcls.foreach(x => aclOperations.add(x.operation())) - } - }) - } + resourceToAcls.foreach(resource => { + if (resource._1.name() == filter.name() && resource._1.resourceType() == filter.resourceType() && resource._1.patternType() == filter.patternType()) { + resource._2.foreach(acl => { + if (acl.host() == "*" && acl.permissionType() == AclPermissionType.ALLOW) { + if (principalAclOperationsMap.contains(acl.principal())) { + principalAclOperationsMap(acl.principal()) += acl.operation() + } + else { + principalAclOperationsMap += (acl.principal() -> Set(acl.operation())) + } + } + }) + } + }) - aclOperations.toSet + principalAclOperationsMap.toMap } } From d1c5d7100ac37b44570c78aa933628a07d372898 Mon Sep 17 00:00:00 2001 From: yangguo Date: Tue, 29 Jun 2021 22:03:32 -0700 Subject: [PATCH 3/3] change function name --- .../microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala b/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala index de1105fc2ca8f..336ad0bf723e2 100644 --- a/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala +++ b/azpubsub/src/main/scala/com/microsoft/azpubsub/kafka/admin/AzPubSubAclCommand.scala @@ -59,7 +59,7 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC if (confirmAction(opts, s"Are you sure you want to delete all ACLs for resource filter `$filter`? (y/n)")) removeAcls(adminClient, acls, filter) } else { - val updatedAcls = removeAclWithDescribeOperation(opts, acls, filteredPrincipalAclOperationsMap) + val updatedAcls = dropAclsWithSharedOperation(opts, acls, filteredPrincipalAclOperationsMap) if (confirmAction(opts, s"Are you sure you want to remove ACLs: $Newline ${updatedAcls.map("\t" + _).mkString(Newline)} $Newline from resource filter `$filter`? (y/n)")) { removeAcls(adminClient, updatedAcls, filter) } @@ -197,7 +197,7 @@ class AzPubSubAdminClientService(opts: AzPubSubAclCommandOptions) extends AdminC producerConsumerGroupAclMap } - def removeAclWithDescribeOperation(opt: AzPubSubAclCommandOptions, acls: Set[AccessControlEntry], principalAclOperationsMap: Map[String, Set[AclOperation]]): Set[AccessControlEntry] ={ + def dropAclsWithSharedOperation(opt: AzPubSubAclCommandOptions, acls: Set[AccessControlEntry], principalAclOperationsMap: Map[String, Set[AclOperation]]): Set[AccessControlEntry] ={ val producerAclOperations = GetProducerAclOperations() val consumerAclOperations = GetConsumerAclOperations()