Skip to content

Comments

KAFKA-6726: Fine Grained ACL for CreateTopics (KIP-277)#4795

Merged
ijuma merged 18 commits intoapache:trunkfrom
edoardocomar:topic_create_acl
Jun 6, 2018
Merged

KAFKA-6726: Fine Grained ACL for CreateTopics (KIP-277)#4795
ijuma merged 18 commits intoapache:trunkfrom
edoardocomar:topic_create_acl

Conversation

@edoardocomar
Copy link
Contributor

  • Handling CreateTopicsRequest now requires Create auth on Topic resource and does not require Create on Cluster

  • AclCommand --producer option adjusted

  • Existing Unit and Integration tests adjusted accordingly

https://issues.apache.org/jira/browse/KAFKA-6726
https://cwiki.apache.org/confluence/display/KAFKA/KIP-277+-+Fine+Grained+ACL+for+CreateTopics+API

Co-authored-by: Edoardo Comar ecomar@uk.ibm.com
Co-authored-by: Mickael Maison mickael.maison@gmail.com

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@ijuma ijuma self-requested a review May 21, 2018 18:58
@ijuma ijuma added this to the 2.0.0 milestone May 21, 2018
@ijuma ijuma self-assigned this May 21, 2018
@ijuma
Copy link
Member

ijuma commented May 24, 2018

Thanks for the PR, let's add an upgrade note, please.

@edoardocomar
Copy link
Contributor Author

Hi @ijuma thanks for reviewing
we rebased, marginally improved testing for auto-create and added upgrade notes done

@edoardocomar
Copy link
Contributor Author

@ijuma last commit was just to resolve merge conflicts

@edoardocomar
Copy link
Contributor Author

test failure unrelated (dynamic broker config)

@ijuma can you please review as the deadline for feature freeze is tomorrow

@ijuma
Copy link
Member

ijuma commented May 29, 2018

This is a small feature, so there's an extra week.

@edoardocomar edoardocomar force-pushed the topic_create_acl branch 2 times, most recently from 03d6a33 to f9034eb Compare May 31, 2018 09:06
Copy link
Member

@ijuma ijuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, a few minor comments after the first pass.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's safer to have asserts for both cases here and in the other place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, added test cases for all code paths

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need new tests here given AuthorizerIntegrationTest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we think so because EndToEndAuthorizationTest uses the acl tool command line

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have AclCommandTest for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, this test was meant to cover some high level end to end cases. It seems OK to add an auto create case, but overkill to add one for Create Topic and another for Create Cluster. We should add a test to AclCommandTest for the latter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I see the AclCommandTest has already coverage of adding cluster create and topic create acls. The AuthorizerIntegrationTest covers all request handling logic with and without auto-create.

So we only left one end2end test case for auto create with topic create acl

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit odd that we are using maps here even though there's a single entry in each. Shall we simplify?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed!

mimaison and others added 5 commits June 4, 2018 16:11
* Handling CreateTopicsRequest now requires Create auth on Topic
resource and does not require Create on Cluster

* AclCommand --producer option adjusted

* Existing Unit and Integration tests adjusted accordingly

https://issues.apache.org/jira/browse/KAFKA-6726
https://cwiki.apache.org/confluence/display/KAFKA/KIP-277+-+Fine+Grained+ACL+for+CreateTopics+API

Co-authored-by: Edoardo Comar <ecomar@uk.ibm.com>
Co-authored-by: Mickael Maison <mickael.maison@gmail.com>

- [ ] Verify design and implementation
- [ ] Verify test coverage and CI build status
- [ ] Verify documentation (including upgrade notes)
* Handling CreateTopicsRequest now requires Create auth on Topic
resource and does not require Create on Cluster

* AclCommand --producer option adjusted

* Existing Unit and Integration tests adjusted accordingly

* upgrade notes

https://issues.apache.org/jira/browse/KAFKA-6726
https://cwiki.apache.org/confluence/display/KAFKA/KIP-277+-+Fine+Grained+ACL+for+CreateTopics+API

Co-authored-by: Edoardo Comar <ecomar@uk.ibm.com>
Co-authored-by: Mickael Maison <mickael.maison@gmail.com>

- [ ] Verify design and implementation
- [ ] Verify test coverage and CI build status
- [ ] Verify documentation (including upgrade notes)
check all paths on topic auto creation

simplified testCreateTopicAuthorizationWithClusterCreate
@edoardocomar
Copy link
Contributor Author

Hi @ijuma thanks for the review - we rebased to address the conflicts and also addressed at your comments

you will notice a weird double call to consumers.head.poll(Duration.ofMillis(50L));
as we wanted the test to check topic auto-creation without a write request but for some reason (unrelated to our changes) the first call to poll after a previously failed one did not trigger the topic auto-creation.

@ijuma ijuma changed the title KAFKA-6726: KIP-277 - Fine Grained ACL for CreateTopics API KAFKA-6726: Fine Grained ACL for CreateTopics API (KIP-277) Jun 5, 2018
@ijuma ijuma changed the title KAFKA-6726: Fine Grained ACL for CreateTopics API (KIP-277) KAFKA-6726: Fine Grained ACL for CreateTopics (KIP-277) Jun 5, 2018
@edoardocomar
Copy link
Contributor Author

about the need for a different poll timeout - I opened another jira, does not seem a critical bug
https://issues.apache.org/jira/browse/KAFKA-6994

Copy link
Member

@ijuma ijuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of quick questions while I review the rest.

(Resource.ClusterResource -> (getAcl(opts, Set(Create)) ++
(if (enableIdempotence) getAcl(opts, Set(IdempotentWrite)) else Set.empty[Acl])))
//Write, Describe, Create permission on topics, Write, Describe on transactionalIds
topics.map(_ -> topicAcls).toMap[Resource, Set[Acl]] ++
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can toMap[Resource, Set[Acl]] be simply toMap? Same for other cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, existing syntax simplified

this.consumers.head.assign(List(topicPartition).asJava)
consumeRecords(this.consumers.head)
Assert.fail("should have thrown exception")
this.consumers.head.poll(Duration.ofMillis(50L));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we replace consumeRecords with poll?

Copy link
Contributor Author

@edoardocomar edoardocomar Jun 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We modified the method to avoid producing any records - to avoid adding write permission which made the test more complicated than it needed to be.

So we need to pass numRecords=0 and we had no control on the timeout, unless we made that another optional argument.
without actually consuming records it seems to me that just calling poll is simpler than consumeRecords

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to be generous with the timeout then. Any reason why it's so low?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default timeout was fine for the first call (when we expect it always to throw)

it's the second one that caused issues - see https://issues.apache.org/jira/browse/KAFKA-6994 - but that IMHO is unrelated to the changes in this PR.

if the second timeout is low - even without adding the required acl the test passed - that's the bug 6994.

if the second timeout is large the test takes longer, that's why we kept relatively short

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you see my comment in KAFKA-6994?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep - replied there - it's the same with the old poll

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even then, poll provides little in the way of guarantees. I suggest using TestUtils.retry with a generous timeout and a short timeout for poll. This also ensures we finish as quickly as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point - we can use waitUntilTrue checking for the topic being created as a consequence of poll


sendRequestAndVerifyResponseError(ApiKeys.CREATE_TOPICS, createTopicsRequest, resources, isAuthorized = false)

clusterCreateAcl.get(topicResource).foreach { acls =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit dangerous because if get returns None, the test will pass.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! - the test did not actually need that block, (get was returning None !) was a sloppy remainder of previous refactoring

} else Map.empty

val completeResults = results ++ duplicatedTopicsResults
val unauthorizedTopicsResults = unauthorizedTopics.keySet.map(_ -> new ApiError(Errors.TOPIC_AUTHORIZATION_FAILED, null))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space after =.

val newTopic = "newTopic"
def testCreatePermissionOnTopicToWriteToNonExistentTopic() {
testCreatePermissionNeededToWriteToNonExistentTopic("newTopic",
Set(new Acl(userPrincipal, Allow, Acl.WildCardHost, Write), new Acl(userPrincipal, Allow, Acl.WildCardHost, Create)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need Write here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, going to simplify by removing the constant arguments

this.consumers.head.assign(List(topicPartition).asJava)
consumeRecords(this.consumers.head)
Assert.fail("should have thrown exception")
this.consumers.head.poll(Duration.ofMillis(50L));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even then, poll provides little in the way of guarantees. I suggest using TestUtils.retry with a generous timeout and a short timeout for poll. This also ensures we finish as quickly as possible.

this.serverConfig.setProperty(KafkaConfig.OffsetsTopicPartitionsProp, "1")
this.serverConfig.setProperty(KafkaConfig.OffsetsTopicReplicationFactorProp, "3")
this.serverConfig.setProperty(KafkaConfig.MinInSyncReplicasProp, "3")
this.serverConfig.setProperty(KafkaConfig.DefaultReplicationFactorProp, "3")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because we added tests which use topic auto-create, so they need a default replication factor matching the min in sync

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks anyway, we spotted a missing @Test :(

if (!authorize(request.session, Create, Resource.ClusterResource)) {
authorizedTopics --= nonExistingTopics
unauthorizedForCreateTopics ++= nonExistingTopics
val unauthorizedForCreateTopics = authorizedTopics.filter(topic => !authorize(request.session, Create, new Resource(Topic, topic)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: long line.

topics.partition(topic => authorize(request.session, Describe, new Resource(Topic, topic)))

var unauthorizedForCreateTopics = Set[String]()
var authorizedForDescribeNotCreateTopics = Set[String]()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we rename this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new name though longer and not pretty matches the what the set of topics actually is in terms of authorizations

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then later we still have things like unauthorizedForCreateTopicMetadata. I think we should just keep this variable as it was since there is no actual change here. I'll push a minor commit.

if (!authorize(request.session, Create, Resource.ClusterResource)) {
authorizedTopics --= nonExistingTopics
unauthorizedForCreateTopics ++= nonExistingTopics
val unauthorizedForCreateTopics = authorizedTopics.filter(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a bug, we should only be doing this check for nonExistingTopics. Will push a fix.

ijuma added 4 commits June 5, 2018 23:43
…grained-acl-create-topics

* apache-github/trunk:
  KAFKA-5588: Remove deprecated --new-consumer tools option (apache#5097)
  MINOR: Fix for the location of the trogdor.sh executable file in the documentation. (apache#5040)
  KAFKA-6997: Exclude test-sources.jar when $INCLUDE_TEST_JARS is FALSE
  MINOR: docs should point to latest version (apache#5132)
  KAFKA-6981: Move the error handling configuration properties into the ConnectorConfig and SinkConnectorConfig classes (KIP-298)
  [KAFKA-6730] Simplify State Store Recovery (apache#5013)
  MINOR: Rename package `internal` to `internals` for consistency (apache#5137)
  KAFKA-6704: InvalidStateStoreException from IQ when StreamThread closes store (apache#4801)
  MINOR: Add missing configs for resilience settings
  MINOR: Add regression tests for KTable mapValues and filter (apache#5134)
  KAFKA-6750: Add listener name to authentication context (KIP-282) (apache#4829)
  KAFKA-3665: Enable TLS hostname verification by default (KIP-294) (apache#4956)
  KAFKA-6938: Add documentation for accessing Headers on Kafka Streams Processor API (apache#5128)
  KAFKA-6813: return to double-counting for count topology names (apache#5075)
  KAFKA-5919; Adding checks on "version" field for tools using it
  MINOR: Remove deprecated KafkaStreams constructors in docs (apache#5118)
Copy link
Member

@ijuma ijuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a few minor changes including a merge conflict fix. This PR LGTM now and I will merge once the tests pass. @edoardocomar, please follow up if you have concerns about any of my changes.

@omkreddy
Copy link
Contributor

omkreddy commented Jun 6, 2018

LGTM

@ijuma ijuma merged commit 0c035c4 into apache:trunk Jun 6, 2018
ijuma added a commit to big-andy-coates/kafka that referenced this pull request Jun 6, 2018
…refix

* apache-github/trunk:
  KAFKA-6726: Fine Grained ACL for CreateTopics (KIP-277) (apache#4795)
  KAFKA-5588: Remove deprecated --new-consumer tools option (apache#5097)
  MINOR: Fix for the location of the trogdor.sh executable file in the documentation. (apache#5040)
  KAFKA-6997: Exclude test-sources.jar when $INCLUDE_TEST_JARS is FALSE
  MINOR: docs should point to latest version (apache#5132)
  KAFKA-6981: Move the error handling configuration properties into the ConnectorConfig and SinkConnectorConfig classes (KIP-298)
  [KAFKA-6730] Simplify State Store Recovery (apache#5013)
  MINOR: Rename package `internal` to `internals` for consistency (apache#5137)
  KAFKA-6704: InvalidStateStoreException from IQ when StreamThread closes store (apache#4801)
  MINOR: Add missing configs for resilience settings
  MINOR: Add regression tests for KTable mapValues and filter (apache#5134)
  KAFKA-6750: Add listener name to authentication context (KIP-282) (apache#4829)
  KAFKA-3665: Enable TLS hostname verification by default (KIP-294) (apache#4956)
  KAFKA-6938: Add documentation for accessing Headers on Kafka Streams Processor API (apache#5128)
  KAFKA-6813: return to double-counting for count topology names (apache#5075)
  KAFKA-5919; Adding checks on "version" field for tools using it
  MINOR: Remove deprecated KafkaStreams constructors in docs (apache#5118)
@edoardocomar
Copy link
Contributor Author

thanks @ijuma

@edoardocomar
Copy link
Contributor Author

@ijuma we looked closely at your commit dc2727e
great that you spotted that we split the wrong collection ...
we added a minor PR to cover that case: #5155

@ijuma
Copy link
Member

ijuma commented Jun 6, 2018

@edoardocomar you read my mind as I was going to ask if you were willing to submit a PR to fix the testing gap. :)

@edoardocomar edoardocomar deleted the topic_create_acl branch June 6, 2018 18:39
ying-zheng pushed a commit to ying-zheng/kafka that referenced this pull request Jul 6, 2018
- CreateTopicsRequest now requires Create auth on Topic resource
or Create on Cluster resource.
- AclCommand --producer option adjusted
- Existing unit and Integration tests adjusted accordingly and
new tests added.

Reviewers: Manikumar Reddy <manikumar.reddy@gmail.com>, Ismael Juma <ismael@juma.me.uk>

Co-authored-by: Edoardo Comar <ecomar@uk.ibm.com>
Co-authored-by: Mickael Maison <mickael.maison@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants