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();

Reply via email to