KAFKA-10747: Implement APIs for altering and describing IP connection rate quotas#9628
Conversation
bdbyrne
left a comment
There was a problem hiding this comment.
LG - only minor comments, thanks for the change!
apovzner
left a comment
There was a problem hiding this comment.
LGTM! Left couple of minor comments.
| val ipDefaults = parser.accepts("ip-defaults", "The config defaults for all IPs.") | ||
| val ip = parser.accepts("ip", "The IP address.") |
There was a problem hiding this comment.
It would be good to add these two flags in the KIP as well for completeness.
There was a problem hiding this comment.
will do, along with the change to lower
There was a problem hiding this comment.
done. while I was updating the KIP, i noticed that the previous config documentation was inconsistent with existing configs.
Default connection rate quotas for an IP address can be configured by omitting entity name.
bin/kafka-configs --bootstrap-server localhost:9091 --alter --add-config 'connection_creation_rate=100' --entity-type IPs
This isn't the case for any of the existing configs, you get an error:
an entity-name or default entity must be specified with --alter of users, clients, brokers
so I also updated the KIP for default IP to specify --entity-default.
|
Thanks for the feedback @dajac |
| def validateIpConfig(ip: String, configs: Properties): Unit = { | ||
| if (ip != ConfigEntityName.Default && !Utils.validHostPattern(ip)) | ||
| throw new AdminOperationException(s"IP $ip is not a valid address.") | ||
| DynamicConfig.Ip.validateIpOrHost(ip) |
There was a problem hiding this comment.
It is a little weird to throw InvalidRequestException here because there is not request involved. Users of AdminZkClient may not expect this. I think that it would be better to throw a IllegalArgumentException. Then in the AdminManager#alterClientQuotas, we can catch it and transform it into InvalidRequestException by copying the internal message.
| } | ||
|
|
||
| if (hasEntityName && entityTypeVals.contains(ConfigType.Ip)) { | ||
| Seq(entityName, ip).filter(options.has(_)).map(options.valueOf(_)).foreach(DynamicConfig.Ip.validateIpOrHost) |
There was a problem hiding this comment.
ditto here. It is a bit weird to have an InvalidRequestException thrown here.
| if (!Utils.validHostPattern(ip)) | ||
| throw new InvalidRequestException(s"$ip is not a valid hostname") |
There was a problem hiding this comment.
I wonder if this step is really necessary as InetAddress.getByName also ensures that the hostname is valid. What do you think?
| try { | ||
| InetAddress.getByName(ip) | ||
| } catch { | ||
| case _ :UnknownHostException => throw new InvalidRequestException(s"$ip is not a valid IP or resolvable hostname") |
There was a problem hiding this comment.
nit: _ :UnknownHostException => _: UnknownHostException
| try { | ||
| DynamicConfig.Ip.validateIpOrHost(ip) | ||
| } catch { | ||
| case e: IllegalArgumentException => throw new InvalidRequestException(e.getMessage) | ||
| } |
There was a problem hiding this comment.
- For my understanding, have you chosen to do the validation here to ensure that requests with
validateOnly = trueare fully validated? - Initially, I thought that we could just catch the
IllegalArgumentExceptionhere . Doing the conversion here seems reasonable as well. Alternatively, we could also changevalidateIpOrHostto return a boolean and let the caller decides which exception to throw.
There was a problem hiding this comment.
@dajac
yes, I thought that catching in that block would work, but after taking a closer look, it seems like entity validation is only done when altering, so we wouldn't hit validation in the validateOnly = true case.
I think changing validateIpOrHost to return a boolean is reasonable. I originally wanted to have it throw exception instead of boolean since we had two validation steps (validHostPattern and then resolvable IP), but since we simplified that code block to only do host resolution, it makes more sense to have it just return a boolean.
| } | ||
|
|
||
| @Test | ||
| def testAlterClientQuotasInvalidEntityCombination(): Unit = { |
There was a problem hiding this comment.
For these three tests, would it make sense to also verify that the error message? InvalidRequestException are thrown all over the place so we may get one but not for the expected cause. Your last commit suggests that you got caught by this already, is it? 1b0ec2a#diff-f02b619b5cd14e83f7e21dbe211b3f88336f825e1ee5c630fee32b8a0fbe3d20R294
|
Failed test is not related:
|
|
@splett2 Thanks for your contribution! |
This PR adds support for IP entities to the
DescribeClientQuotasandAlterClientQuotasAPIs. This change does not require any protocol version bumps.This PR also adds support for describing/altering IP quotas via
kafka-configstooling.Committer Checklist (excluded from commit message)