-
Notifications
You must be signed in to change notification settings - Fork 14.3k
KAFKA-18870 Implement describeDelegationToken for controller #19306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
8b3c702
d615766
c7cfb1c
298d524
e0cf08b
e243403
c06e5e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ | |
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.Properties; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.stream.Stream; | ||
|
@@ -181,12 +182,15 @@ public static List<DelegationToken> describeToken(Admin adminClient, DelegationT | |
|
||
private static Admin createAdminClient(DelegationTokenCommandOptions opts) throws IOException { | ||
Properties props = Utils.loadProps(opts.options.valueOf(opts.commandConfigOpt)); | ||
props.put("bootstrap.servers", opts.options.valueOf(opts.bootstrapServerOpt)); | ||
CommandLineUtils.initializeBootstrapProperties(props, | ||
Optional.ofNullable(opts.options.valueOf(opts.bootstrapServerOpt)), | ||
Optional.ofNullable(opts.options.valueOf(opts.bootstrapControllerOpt))); | ||
return Admin.create(props); | ||
} | ||
|
||
static class DelegationTokenCommandOptions extends CommandDefaultOptions { | ||
public final OptionSpec<String> bootstrapServerOpt; | ||
public final OptionSpec<String> bootstrapControllerOpt; | ||
public final OptionSpec<String> commandConfigOpt; | ||
public final OptionSpec<Void> createOpt; | ||
public final OptionSpec<Void> renewOpt; | ||
|
@@ -202,14 +206,20 @@ static class DelegationTokenCommandOptions extends CommandDefaultOptions { | |
public DelegationTokenCommandOptions(String[] args) { | ||
super(args); | ||
|
||
String bootstrapServerDoc = "REQUIRED: server(s) to use for bootstrapping."; | ||
String bootstrapServerDoc = "REQUIRED: server(s) to use for bootstrapping. When the --bootstrap-controller argument is used --bootstrap-servers must not be specified."; | ||
String commandConfigDoc = "REQUIRED: A property file containing configs to be passed to Admin Client. Token management" + | ||
" operations are allowed in secure mode only. This config file is used to pass security related configs."; | ||
String bootstrapControllerDoc = "REQUIRED: A comma-separated list of bootstrap.controllers that can be supplied instead of bootstrap-servers." | ||
+ " This is useful for administrators who wish to bypass the brokers."; | ||
|
||
this.bootstrapServerOpt = parser.accepts("bootstrap-server", bootstrapServerDoc) | ||
.withRequiredArg() | ||
.ofType(String.class); | ||
|
||
this.bootstrapControllerOpt = parser.accepts("bootstrap-controller", bootstrapControllerDoc) | ||
.withRequiredArg() | ||
.ofType(String.class); | ||
|
||
this.commandConfigOpt = parser.accepts("command-config", commandConfigDoc) | ||
.withRequiredArg() | ||
.ofType(String.class); | ||
|
@@ -284,7 +294,7 @@ public String hmac() { | |
|
||
public void checkArgs() { | ||
// check required args | ||
CommandLineUtils.checkRequiredArgs(parser, options, bootstrapServerOpt, commandConfigOpt); | ||
CommandLineUtils.checkRequiredArgs(parser, options, commandConfigOpt); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed https://github.com/apache/kafka/pull/19306/files#r2034702639 here. |
||
|
||
if (options.has(createOpt)) { | ||
CommandLineUtils.checkRequiredArgs(parser, options, maxLifeTimeOpt); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,17 +17,32 @@ | |
package org.apache.kafka.tools; | ||
|
||
import org.apache.kafka.clients.admin.Admin; | ||
import org.apache.kafka.clients.admin.CreateDelegationTokenOptions; | ||
import org.apache.kafka.clients.admin.CreateDelegationTokenResult; | ||
import org.apache.kafka.clients.admin.DescribeDelegationTokenResult; | ||
import org.apache.kafka.clients.admin.MockAdminClient; | ||
import org.apache.kafka.common.security.auth.SecurityProtocol; | ||
import org.apache.kafka.common.security.token.delegation.DelegationToken; | ||
import org.apache.kafka.common.test.ClusterInstance; | ||
import org.apache.kafka.common.test.api.ClusterConfigProperty; | ||
import org.apache.kafka.common.test.api.ClusterTest; | ||
import org.apache.kafka.common.test.api.Type; | ||
import org.apache.kafka.common.utils.SecurityUtils; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.io.TempDir; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.ExecutionException; | ||
|
||
import static org.apache.kafka.server.config.DelegationTokenManagerConfigs.DELEGATION_TOKEN_SECRET_KEY_CONFIG; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
@@ -81,6 +96,36 @@ public void testDelegationTokenRequests() throws ExecutionException, Interrupted | |
|
||
} | ||
|
||
@Test | ||
public void testSetBootstrapServerAndBootstrapController(@TempDir Path configPath) throws IOException { | ||
Path testFile = Files.createFile(configPath.resolve("testfile")); | ||
assertThrows(RuntimeException.class, | ||
() -> DelegationTokenCommand.execute("--bootstrap-server", "localhost:9092", | ||
"--bootstrap-controller", "localhost:9092", | ||
"--command-config", testFile.toString(), "--describe")); | ||
} | ||
|
||
@ClusterTest(types = { Type.KRAFT }, | ||
brokerSecurityProtocol = SecurityProtocol.SASL_PLAINTEXT, | ||
controllerSecurityProtocol = SecurityProtocol.SASL_PLAINTEXT, | ||
serverProperties = { | ||
@ClusterConfigProperty(key = DELEGATION_TOKEN_SECRET_KEY_CONFIG, value = "key") | ||
}) | ||
public void testDescribeDelegationTokenWithBootstrapController(ClusterInstance clusterInstance) throws ExecutionException, InterruptedException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test case is about Admin. We need another test case to test DelegationTokenCommand directly. |
||
try (Admin brokerAdmin = clusterInstance.admin(); | ||
Admin controllerAdmin = clusterInstance.admin(Map.of(), true)) { | ||
CreateDelegationTokenOptions ops = new CreateDelegationTokenOptions() | ||
.renewers(List.of(SecurityUtils.parseKafkaPrincipal("User:user1"))); | ||
CreateDelegationTokenResult createResult = brokerAdmin.createDelegationToken(ops); | ||
DelegationToken expected = createResult.delegationToken().get(); | ||
clusterInstance.waitForToken(); | ||
|
||
DescribeDelegationTokenResult describeResult = controllerAdmin.describeDelegationToken(); | ||
DelegationToken actual = describeResult.delegationTokens().get().get(0); | ||
assertEquals(expected, actual); | ||
} | ||
} | ||
|
||
private DelegationTokenCommand.DelegationTokenCommandOptions getCreateOpts(String renewer) { | ||
String[] args = {"--bootstrap-server", "localhost:9092", "--max-life-time-period", "-1", "--command-config", "testfile", "--create", "--renewer-principal", renewer}; | ||
return new DelegationTokenCommand.DelegationTokenCommandOptions(args); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cannot specify both
--bootstrap-server
and--bootstrap-controller
as required. This makes result like:Please using
withOptionalArg
and do the check incheckArgs
.