This is an automated email from the ASF dual-hosted git repository. mpetrov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 984d9ae8668 IGNITE-22844 Fixed permissions required by control.sh --consistency repair command (#11456) 984d9ae8668 is described below commit 984d9ae86681132bb5622719e8c835c50ab0c373 Author: Maksim Davydov <70368398+maksa...@users.noreply.github.com> AuthorDate: Fri Aug 9 16:38:43 2024 +0300 IGNITE-22844 Fixed permissions required by control.sh --consistency repair command (#11456) --- .../SecurityCommandHandlerPermissionsTest.java | 8 +- .../util/GridCommandHandlerConsistencyTest.java | 98 +++++++++++++++++----- .../consistency/ConsistencyRepairTask.java | 4 +- 3 files changed, 84 insertions(+), 26 deletions(-) diff --git a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java index 25c4d2cd71f..59df6748ece 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java @@ -53,13 +53,13 @@ import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.sys /** */ public class SecurityCommandHandlerPermissionsTest extends GridCommandHandlerAbstractTest { /** */ - private static final String TEST_NO_PERMISSIONS_LOGIN = "no-permissions-login"; + public static final String TEST_NO_PERMISSIONS_LOGIN = "no-permissions-login"; /** */ - private static final String TEST_LOGIN = "cli-admin-login"; + public static final String TEST_LOGIN = "cli-admin-login"; /** */ - private static final String DEFAULT_PWD = "pwd"; + public static final String DEFAULT_PWD = "pwd"; /** */ @Parameterized.Parameters(name = "cmdHnd={0}") @@ -164,7 +164,7 @@ public class SecurityCommandHandlerPermissionsTest extends GridCommandHandlerAbs } /** */ - List<String> enrichWithConnectionArguments(Collection<String> cmdArgs, String login) { + public static List<String> enrichWithConnectionArguments(Collection<String> cmdArgs, String login) { List<String> args = new ArrayList<>(); args.add(CMD_USER); diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java index 670b925bb2c..9e2556729db 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java @@ -17,7 +17,9 @@ package org.apache.ignite.util; +import java.security.Permissions; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadLocalRandom; @@ -39,6 +41,8 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.IgniteInternalCache; import org.apache.ignite.internal.processors.cache.version.GridCacheVersionManager; import org.apache.ignite.internal.processors.dr.GridDrType; +import org.apache.ignite.internal.processors.security.impl.TestSecurityData; +import org.apache.ignite.internal.processors.security.impl.TestSecurityPluginProvider; import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; @@ -48,11 +52,20 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import static java.util.Arrays.asList; import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_UNEXPECTED_ERROR; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.DEFAULT_PWD; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.TEST_LOGIN; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.TEST_NO_PERMISSIONS_LOGIN; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.enrichWithConnectionArguments; import static org.apache.ignite.internal.management.consistency.ConsistencyRepairTask.CONSISTENCY_VIOLATIONS_FOUND; +import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_OPS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.ALL_PERMISSIONS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.NO_PERMISSIONS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.systemPermissions; import static org.apache.ignite.testframework.GridTestUtils.assertContains; import static org.apache.ignite.testframework.LogListener.matches; @@ -92,19 +105,22 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster protected final ListeningTestLogger listeningLog = new ListeningTestLogger(log); /** */ - @Parameterized.Parameters(name = "cmdHnd={0}, strategy={1}, explicitGrp={2}, callByGrp={3}") + @Parameterized.Parameters(name = "cmdHnd={0}, strategy={1}, explicitGrp={2}, callByGrp={3}, withSecurityEnabled={4}") public static Iterable<Object[]> data() { List<Object[]> res = new ArrayList<>(); - int cntr = 0; - List<String> invokers = commandHandlers(); - - for (ReadRepairStrategy strategy : ReadRepairStrategy.values()) { - for (boolean explicitGrp : new boolean[]{false, true}) { - if (explicitGrp) - res.add(new Object[]{invokers.get(cntr++ % invokers.size()), strategy, explicitGrp, true}); - - res.add(new Object[]{invokers.get(cntr++ % invokers.size()), strategy, explicitGrp, false}); + for (String invoker : commandHandlers()) { + for (ReadRepairStrategy strategy : ReadRepairStrategy.values()) { + for (boolean explicitGrp : new boolean[] {false, true}) { + for (boolean callByGrp : new boolean[] {false, true}) { + for (boolean withSecurityEnabled : new boolean[] {false, true}) { + if (!explicitGrp && callByGrp || invoker.equals(JMX_CMD_HND) && withSecurityEnabled) + continue; + + res.add(new Object[] {invoker, strategy, explicitGrp, callByGrp, withSecurityEnabled}); + } + } + } } } @@ -129,6 +145,12 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster @Parameterized.Parameter(3) public boolean callByGrp; + /** + * True if security checks enabled. + */ + @Parameterized.Parameter(4) + public boolean withSecurityEnabled; + /** * */ @@ -154,6 +176,18 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster cfg.setGridLogger(listeningLog); + if (withSecurityEnabled) { + cfg.setPluginProviders( + new TestSecurityPluginProvider( + igniteInstanceName, + DEFAULT_PWD, + ALL_PERMISSIONS, + false, + new TestSecurityData(TEST_NO_PERMISSIONS_LOGIN, DEFAULT_PWD, NO_PERMISSIONS, new Permissions()), + new TestSecurityData(TEST_LOGIN, DEFAULT_PWD, systemPermissions(ADMIN_OPS), new Permissions())) + ); + } + return cfg; } @@ -221,7 +255,8 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster } } - assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify")); + checkCommandExecution(EXIT_CODE_OK, asList("--cache", "idle_verify")); + assertContains(log, testOut.toString(), "conflict partitions has been found: [counterConflicts=0, hashConflicts=" + brokenParts.get()); @@ -285,7 +320,8 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster AtomicInteger brokenParts = new AtomicInteger(PARTITIONS); - assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify")); + checkCommandExecution(EXIT_CODE_OK, asList("--cache", "idle_verify")); + assertContains(log, testOut.toString(), "conflict partitions has been found: [counterConflicts=0, hashConflicts=" + brokenParts.get()); @@ -306,11 +342,13 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster injectTestSystemOut(); for (int i = 0; i < PARTITIONS; i++) { - assertEquals(EXIT_CODE_UNEXPECTED_ERROR, - execute("--consistency", "repair", + checkCommandExecution( + EXIT_CODE_UNEXPECTED_ERROR, + asList("--consistency", "repair", CACHE, "non-existent", PARTITIONS_ARG, String.valueOf(i), - STRATEGY, strategy.toString())); + STRATEGY, strategy.toString()) + ); assertTrue(ConsistencyStatusTask.MAP.isEmpty()); @@ -329,18 +367,20 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster i = Math.min(i + ThreadLocalRandom.current().nextInt(1, 10), PARTITIONS); - assertEquals(EXIT_CODE_OK, execute("--consistency", "repair", - CACHE, callByGrp ? cacheName + GRP_POSTFIX : cacheName, - PARTITIONS_ARG, - IntStream.range(from, i).mapToObj(Integer::toString).collect(Collectors.joining(",")), - STRATEGY, strategy.toString())); + checkCommandExecution( + EXIT_CODE_OK, + asList("--consistency", "repair", + CACHE, callByGrp ? cacheName + GRP_POSTFIX : cacheName, + PARTITIONS_ARG, IntStream.range(from, i).mapToObj(Integer::toString).collect(Collectors.joining(",")), + STRATEGY, strategy.toString()) + ); assertTrue(ConsistencyStatusTask.MAP.isEmpty()); assertContains(log, testOut.toString(), CONSISTENCY_VIOLATIONS_FOUND); assertContains(log, testOut.toString(), "[found=1, repaired=" + repairsPerEntry.toString()); - assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify")); + checkCommandExecution(EXIT_CODE_OK, asList("--cache", "idle_verify")); if (repairsPerEntry > 0) { brokenParts.addAndGet(-(i - from)); @@ -444,4 +484,20 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster protected boolean binaryCache() { return false; } + + /** + * Wrapper for security check with {@link #assertEquals(int, int)}. The method checks 2 user logins + * for auth success/error. + * @param expExitCode Exp exit code. + * @param cmdArgs cmdArgs command arguments + */ + private void checkCommandExecution(int expExitCode, Collection<String> cmdArgs) { + if (!withSecurityEnabled) + assertEquals(expExitCode, execute(new ArrayList<>(cmdArgs))); + else { + assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute(enrichWithConnectionArguments(cmdArgs, TEST_NO_PERMISSIONS_LOGIN))); + + assertEquals(expExitCode, execute(enrichWithConnectionArguments(cmdArgs, TEST_LOGIN))); + } + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java b/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java index 7495ba4217c..0a46c30d73b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition; import org.apache.ignite.internal.processors.cache.distributed.near.consistency.IgniteIrreparableConsistencyViolationException; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; +import org.apache.ignite.internal.processors.security.OperationSecurityContext; import org.apache.ignite.internal.util.GridConcurrentHashSet; import org.apache.ignite.internal.util.lang.GridCursor; import org.apache.ignite.internal.util.typedef.F; @@ -48,6 +49,7 @@ import org.apache.ignite.internal.visor.VisorJob; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.resources.LoggerResource; + import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION; /** @@ -271,7 +273,7 @@ public class ConsistencyRepairTask extends AbstractConsistencyTask<ConsistencyRe * @param keys Keys. */ private void repair(IgniteCache<Object, Object> cache, Set<Object> keys) { - try { + try (OperationSecurityContext ignored = ignite.context().security().withContext(ignite.localNode().id())) { cache.getAll(keys); // Repair. } catch (CacheException e) {