AMBARI-21757. Allow for keytab regeneration to be filtered for hosts (echekanskiy)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b155c1a7 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b155c1a7 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b155c1a7 Branch: refs/heads/feature-branch-AMBARI-21307 Commit: b155c1a770fad1c268166be0bd5f34f589319d83 Parents: 0a2eccd Author: Eugene Chekanskiy <echekans...@apache.org> Authored: Wed Aug 23 15:48:29 2017 +0300 Committer: Eugene Chekanskiy <echekans...@apache.org> Committed: Wed Aug 23 15:48:29 2017 +0300 ---------------------------------------------------------------------- .../resources/ClusterResourceDefinition.java | 2 + .../server/controller/KerberosHelper.java | 8 ++++ .../server/controller/KerberosHelperImpl.java | 47 +++++++++++++++++++- .../server/controller/KerberosHelperTest.java | 30 +++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/b155c1a7/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java index f689841..8933dd3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java @@ -85,6 +85,8 @@ public class ClusterResourceDefinition extends BaseResourceDefinition { directives.add(KerberosHelper.DIRECTIVE_REGENERATE_KEYTABS); directives.add(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES); directives.add(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS); + directives.add(KerberosHelper.DIRECTIVE_HOSTS); + directives.add(KerberosHelper.DIRECTIVE_COMPONENTS); return directives; } http://git-wip-us.apache.org/repos/asf/ambari/blob/b155c1a7/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java index 3819863..a334542 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java @@ -50,6 +50,14 @@ public interface KerberosHelper { */ String DIRECTIVE_REGENERATE_KEYTABS = "regenerate_keytabs"; /** + * directive used to pass host list to regenerate keytabs on + */ + String DIRECTIVE_HOSTS = "regenerate_hosts"; + /** + * directive used to pass list of services and their components to regenerate keytabs for + */ + String DIRECTIVE_COMPONENTS = "regenerate_components"; + /** * directive used to indicate that the enable Kerberos operation should proceed even if the * cluster's security type is not changing */ http://git-wip-us.apache.org/repos/asf/ambari/blob/b155c1a7/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java index 6c6c439..8d0fd0f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java @@ -122,6 +122,8 @@ import org.apache.directory.server.kerberos.shared.keytab.Keytab; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Singleton; @@ -254,6 +256,9 @@ public class KerberosHelperImpl implements KerberosHelper { CreatePrincipalsAndKeytabsHandler handler = null; + Set<String> hostFilter = parseHostFilter(requestProperties); + Map<String, Set<String>> serviceComponentFilter = parseComponentFilter(requestProperties); + if ("true".equalsIgnoreCase(value) || "all".equalsIgnoreCase(value)) { handler = new CreatePrincipalsAndKeytabsHandler(true, true, true); } else if ("missing".equalsIgnoreCase(value)) { @@ -262,7 +267,7 @@ public class KerberosHelperImpl implements KerberosHelper { if (handler != null) { requestStageContainer = handle(cluster, getKerberosDetails(cluster, manageIdentities), - null, null, null, null, requestStageContainer, handler); + serviceComponentFilter, hostFilter, null, null, requestStageContainer, handler); } else { throw new AmbariException(String.format("Unexpected directive value: %s", value)); } @@ -279,6 +284,46 @@ public class KerberosHelperImpl implements KerberosHelper { return requestStageContainer; } + /** + * Parsing 'Kerberos/hosts' property to get list of hosts for 'regenerate_keytabs' request. + * Must be a string with coma separated list of hosts. Absent or miss-spelled hosts must be silently ignored + * by caller code. + * + * @param requestProperties + * @return + */ + public static Set<String> parseHostFilter(final Map<String, String> requestProperties) { + if (requestProperties.containsKey(DIRECTIVE_HOSTS)) { + return ImmutableSet.copyOf(requestProperties.get(DIRECTIVE_HOSTS).split(",")); + } + return null; + } + + /** + * Parsing 'Kerberos/components' property to get list of components for 'regenerate_keytabs' request. + * Must be a comma separated list of strings that follow pattern 'SERVICENAME:COMPONENTNAME;ANOTHERCOMPONENTNAME'. + * For example: HDFS:NAMENODE;DATANODE,YARN:RESOURCEMANAGER,ZOOKEEPER:ZOOKEEPER_SERVER;ZOOKEEPER_CLIENT. + * Absent or miss-spelled components and services must be silently ignored by caller code. + * + * @param requestProperties + * @return + */ + public static Map<String, Set<String>> parseComponentFilter(final Map<String, String> requestProperties) { + if (requestProperties.containsKey(DIRECTIVE_COMPONENTS)) { + ImmutableMap.Builder<String, Set<String>> serviceComponentFilter = ImmutableMap.builder(); + for (String serviceString : requestProperties.get(DIRECTIVE_COMPONENTS).split(",")) { + String[] serviceComponentsArray = serviceString.split(":"); + String serviceName = serviceComponentsArray[0]; + if (serviceComponentsArray.length == 2) { + serviceComponentFilter.put(serviceName, ImmutableSet.copyOf(serviceComponentsArray[1].split(";"))); + } else { + serviceComponentFilter.put(serviceName, null); + } + } + return serviceComponentFilter.build(); + } + return null; + } @Override public RequestStageContainer ensureIdentities(Cluster cluster, Map<String, ? extends Collection<String>> serviceComponentFilter, http://git-wip-us.apache.org/repos/asf/ambari/blob/b155c1a7/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java index b220999..78d464b 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.controller; +import static org.apache.ambari.server.controller.KerberosHelper.DIRECTIVE_COMPONENTS; +import static org.apache.ambari.server.controller.KerberosHelper.DIRECTIVE_HOSTS; import static org.easymock.EasyMock.anyLong; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.anyString; @@ -2596,6 +2598,34 @@ public class KerberosHelperTest extends EasyMockSupport { assertEquals(0, capturedPrincipalsForKeytab.size()); } + @Test + public void testFiltersParsing(){ + Map<String, String> requestProperties = new HashMap<String, String>() {{ + put(DIRECTIVE_HOSTS, "host1,host2,host3"); + put(DIRECTIVE_COMPONENTS, "SERVICE1:COMPONENT1;COMPONENT2,SERVICE2:COMPONENT1;COMPONENT2;COMPONENT3"); + }}; + + Set<String> expectedHosts = new HashSet<String>(Arrays.asList("host1", "host2", "host3")); + Set<String> hosts = KerberosHelperImpl.parseHostFilter(requestProperties); + + assertEquals(expectedHosts, hosts); + + Map<String, Set<String>> expectedComponents = new HashMap<String, Set<String>>(){{ + put("SERVICE1", new HashSet<String>(){{ + add("COMPONENT1"); + add("COMPONENT2"); + }}); + put("SERVICE2", new HashSet<String>(){{ + add("COMPONENT1"); + add("COMPONENT2"); + add("COMPONENT3"); + }}); + }}; + Map<String, Set<String>> components = KerberosHelperImpl.parseComponentFilter(requestProperties); + + assertEquals(expectedComponents, components); + } + private void setupKerberosDescriptor(KerberosDescriptor kerberosDescriptor) throws Exception { // cluster.getCurrentStackVersion expectation is already specified in main test method expect(metaInfo.getKerberosDescriptor("HDP", "2.2")).andReturn(kerberosDescriptor).anyTimes();