You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2015/06/04 01:58:18 UTC

ambari git commit: AMBARI-11629. Falcon version command failed on secure runs (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/trunk 77040938d -> a86701cc4


AMBARI-11629. Falcon version command failed on secure runs (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a86701cc
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a86701cc
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a86701cc

Branch: refs/heads/trunk
Commit: a86701cc465a8e32ce92e713eeedf76bc52a03bc
Parents: 7704093
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Jun 3 19:58:03 2015 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Jun 3 19:58:03 2015 -0400

----------------------------------------------------------------------
 .../server/controller/AuthToLocalBuilder.java   |  91 ++++++++++++-
 .../server/controller/KerberosHelperImpl.java   |  28 +++-
 .../FALCON/0.5.0.2.1/kerberos.json              |   2 +-
 .../server/controller/KerberosHelperTest.java   | 131 ++++++++++++++++++-
 4 files changed, 236 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a86701cc/ambari-server/src/main/java/org/apache/ambari/server/controller/AuthToLocalBuilder.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AuthToLocalBuilder.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AuthToLocalBuilder.java
index c599cc1..89d0b55 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AuthToLocalBuilder.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AuthToLocalBuilder.java
@@ -52,6 +52,7 @@ import java.util.regex.Pattern;
  *
  */
 public class AuthToLocalBuilder {
+  public static final ConcatenationType DEFAULT_CONCATENATION_TYPE = ConcatenationType.NEW_LINES;
 
   /**
    * Ordered set of rules which have been added to the builder.
@@ -116,33 +117,71 @@ public class AuthToLocalBuilder {
 
   /**
    * Generates the auth_to_local rules used by configuration settings such as core-site/auth_to_local.
+   * <p/>
+   * Each rule is concatenated using the default ConcatenationType, like calling
+   * {@link #generate(String, ConcatenationType)} with {@link #DEFAULT_CONCATENATION_TYPE}
    *
    * @param realm a string declaring the realm to use in rule set
-   *
+   * @return a string containing the generated auth-to-local rule set
    */
   public String generate(String realm) {
+    return generate(realm, null);
+  }
+
+  /**
+   * Generates the auth_to_local rules used by configuration settings such as core-site/auth_to_local.
+   * <p/>
+   * Each rule is concatenated using the specified
+   * {@link org.apache.ambari.server.controller.AuthToLocalBuilder.ConcatenationType}.
+   * If the concatenation type is <code>null</code>, the default concatenation type is assumed -
+   * see {@link #DEFAULT_CONCATENATION_TYPE}.
+   *
+   * @param realm             a string declaring the realm to use in rule set
+   * @param concatenationType the concatenation type to use to generate the rule set string
+   * @return a string containing the generated auth-to-local rule set
+   */
+  public String generate(String realm, ConcatenationType concatenationType) {
     StringBuilder builder = new StringBuilder();
     // ensure that a default rule is added for this realm
     setRules.add(createDefaultRealmRule(realm));
 
+    if (concatenationType == null) {
+      concatenationType = DEFAULT_CONCATENATION_TYPE;
+    }
+
     for (Rule rule : setRules) {
-      appendRule(builder, rule.toString());
+      appendRule(builder, rule.toString(), concatenationType);
     }
 
-    appendRule(builder, "DEFAULT");
+    appendRule(builder, "DEFAULT", concatenationType);
     return builder.toString();
   }
 
   /**
    * Append a rule to the given string builder.
    *
-   * @param stringBuilder  string builder to which rule is added
-   * @param rule           rule to add
+   * @param stringBuilder     string builder to which rule is added
+   * @param rule              rule to add
+   * @param concatenationType the concatenation type to use to generate the rule set string
    */
-  private void appendRule(StringBuilder stringBuilder, String rule) {
+  private void appendRule(StringBuilder stringBuilder, String rule, ConcatenationType concatenationType) {
     if (stringBuilder.length() > 0) {
-      stringBuilder.append('\n');
+      switch (concatenationType) {
+        case NEW_LINES:
+          stringBuilder.append('\n');
+          break;
+        case NEW_LINES_ESCAPED:
+          stringBuilder.append("\\\n");
+          break;
+        case SPACES:
+          stringBuilder.append(" ");
+          break;
+        default:
+          throw new UnsupportedOperationException(String.format("The auth-to-local rule concatenation type is not supported: %s",
+              concatenationType.name()));
+      }
     }
+
     stringBuilder.append(rule);
   }
 
@@ -508,4 +547,42 @@ public class AuthToLocalBuilder {
       return result;
     }
   }
+
+  /**
+   * ConcatenationType is an enumeration of auth-to-local rule concatenation types.
+   */
+  public enum ConcatenationType {
+    /**
+     * Each rule is appended to the set of rules on a new line (<code>\n</code>)
+     */
+    NEW_LINES,
+    /**
+     * Each rule is appended to the set of rules on a new line, escaped using a \ (<code>\\n</code>)
+     */
+    NEW_LINES_ESCAPED,
+    /**
+     * Each rule is appended to the set of rules using a space - the ruleset exists on a single line
+     */
+    SPACES;
+
+    /**
+     * Translate a string declaring a concatenation type to the enumerated value.
+     * <p/>
+     * If the string value is <code>null</code> or empty, return the default type - {@link #NEW_LINES}.
+     *
+     * @param value a value to translate
+     * @return a ConcatenationType
+     */
+    public static ConcatenationType translate(String value) {
+      if(value != null) {
+        value = value.trim();
+
+        if(!value.isEmpty()) {
+          return valueOf(value.toUpperCase());
+        }
+      }
+
+      return DEFAULT_CONCATENATION_TYPE;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a86701cc/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 70d08ba..76054b7 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
@@ -115,6 +115,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @Singleton
 public class KerberosHelperImpl implements KerberosHelper {
@@ -129,6 +131,17 @@ public class KerberosHelperImpl implements KerberosHelper {
    */
   private static final String SERVICE_CHECK_IDENTIFIER = "_kerberos_internal_service_check_identifier";
 
+  /**
+   * Regular expression pattern used to parse auth_to_local property specifications into the following
+   * parts:
+   * <ul>
+   * <li>configuration type (optional, if _global_)</li>
+   * <li>property name</li>
+   * <li>concatenation type (optional, if using the default behavior)</li>
+   * </ul>
+   */
+  private static final Pattern AUTH_TO_LOCAL_PROPERTY_SPECIFICATION_PATTERN = Pattern.compile("^(?:(.+?)/)?(.+?)(?:\\|(.+?))?$");
+
   @Inject
   private AmbariCustomCommandExecutionHelper customCommandExecutionHelper;
 
@@ -393,12 +406,16 @@ public class KerberosHelperImpl implements KerberosHelper {
 
       if (!authToLocalPropertiesToSet.isEmpty()) {
         for (String authToLocalProperty : authToLocalPropertiesToSet) {
-          String[] parts = authToLocalProperty.split("/");
+          Matcher m = AUTH_TO_LOCAL_PROPERTY_SPECIFICATION_PATTERN.matcher(authToLocalProperty);
 
-          if (parts.length == 2) {
+          if(m.matches()) {
             AuthToLocalBuilder builder = authToLocalBuilder.copy();
-            String configType = parts[0];
-            String propertyName = parts[1];
+            String configType = m.group(1);
+            String propertyName = m.group(2);
+
+            if(configType == null) {
+              configType = "";
+            }
 
             // Add existing auth_to_local configuration, if set
             Map<String, String> existingConfiguration = existingConfigurations.get(configType);
@@ -415,7 +432,8 @@ public class KerberosHelperImpl implements KerberosHelper {
               kerberosConfigurations.put(configType, kerberosConfiguration);
             }
 
-            kerberosConfiguration.put(propertyName, builder.generate(realm));
+            kerberosConfiguration.put(propertyName, builder.generate(realm,
+                AuthToLocalBuilder.ConcatenationType.translate(m.group(3))));
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a86701cc/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/kerberos.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/kerberos.json b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/kerberos.json
index df3ba34..ac5f49e 100644
--- a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/kerberos.json
+++ b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/kerberos.json
@@ -23,7 +23,7 @@
         }
       ],
       "auth_to_local_properties" : [
-        "falcon-startup.properties/*.falcon.http.authentication.kerberos.name.rules"
+        "falcon-startup.properties/*.falcon.http.authentication.kerberos.name.rules|new_lines_escaped"
       ],
       "components": [
         {

http://git-wip-us.apache.org/repos/asf/ambari/blob/a86701cc/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 58013e2..5744b53 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
@@ -19,9 +19,8 @@
 package org.apache.ambari.server.controller;
 
 import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.junit.Assert.*;
 
 import java.io.File;
 import java.lang.reflect.Field;
@@ -32,6 +31,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -1653,6 +1653,131 @@ public class KerberosHelperTest extends EasyMockSupport {
     ));
   }
 
+  @Test
+  public void testSetAuthToLocalRules() throws Exception {
+    KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
+
+    final KerberosPrincipalDescriptor principalDescriptor1 = createMock(KerberosPrincipalDescriptor.class);
+    expect(principalDescriptor1.getValue()).andReturn("principal1/host1@EXAMPLE.COM").times(1);
+    expect(principalDescriptor1.getLocalUsername()).andReturn("principal1_user").times(1);
+
+    final KerberosPrincipalDescriptor principalDescriptor2 = createMock(KerberosPrincipalDescriptor.class);
+    expect(principalDescriptor2.getValue()).andReturn("principal2/host2@EXAMPLE.COM").times(1);
+    expect(principalDescriptor2.getLocalUsername()).andReturn("principal2_user").times(1);
+
+    final KerberosPrincipalDescriptor principalDescriptor3 = createMock(KerberosPrincipalDescriptor.class);
+    expect(principalDescriptor3.getValue()).andReturn("principal3/host3@EXAMPLE.COM").times(1);
+    expect(principalDescriptor3.getLocalUsername()).andReturn("principal3_user").times(1);
+
+    final KerberosIdentityDescriptor identityDescriptor1 = createMock(KerberosIdentityDescriptor.class);
+    expect(identityDescriptor1.getPrincipalDescriptor()).andReturn(principalDescriptor1).times(1);
+//    expect(identityDescriptor1.getName()).andReturn("1").times(1);
+
+    final KerberosIdentityDescriptor identityDescriptor2 = createMock(KerberosIdentityDescriptor.class);
+    expect(identityDescriptor2.getPrincipalDescriptor()).andReturn(principalDescriptor2).times(1);
+//    expect(identityDescriptor2.getName()).andReturn("2").times(1);
+
+    final KerberosIdentityDescriptor identityDescriptor3 = createMock(KerberosIdentityDescriptor.class);
+    expect(identityDescriptor3.getPrincipalDescriptor()).andReturn(principalDescriptor3).times(1);
+//    expect(identityDescriptor3.getName()).andReturn("3").times(1);
+
+    final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class);
+    expect(serviceDescriptor1.getName()).andReturn("SERVICE1").times(1);
+    expect(serviceDescriptor1.getIdentities(true)).andReturn(Arrays.asList(
+        identityDescriptor1,
+        identityDescriptor2,
+        identityDescriptor3
+    )).times(1);
+    expect(serviceDescriptor1.getComponents()).andReturn(null).times(1);
+    expect(serviceDescriptor1.getAuthToLocalProperties()).andReturn(new HashSet<String>(Arrays.asList(
+        "default",
+        "explicit_multiple_lines|new_lines",
+        "explicit_multiple_lines_escaped|new_lines_escaped",
+        "explicit_single_line|spaces",
+        "service-site/default",
+        "service-site/explicit_multiple_lines|new_lines",
+        "service-site/explicit_multiple_lines_escaped|new_lines_escaped",
+        "service-site/explicit_single_line|spaces"
+    ))).times(1);
+
+    final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class);
+    expect(kerberosDescriptor.getIdentities()).andReturn(null).times(1);
+    expect(kerberosDescriptor.getAuthToLocalProperties()).andReturn(null).times(1);
+    expect(kerberosDescriptor.getServices()).andReturn(Collections.singletonMap("SERVICE1", serviceDescriptor1)).times(1);
+
+    final Service service1 = createNiceMock(Service.class);
+
+    final Cluster cluster = createNiceMock(Cluster.class);
+    expect(cluster.getServices()).andReturn(Collections.singletonMap("SERVICE1", service1)).times(1);
+
+    Map<String, Map<String, String>> kerberosConfigurations = new HashMap<String, Map<String, String>>();
+
+    replayAll();
+
+    // Needed by infrastructure
+    injector.getInstance(AmbariMetaInfo.class).init();
+
+    kerberosHelper.setAuthToLocalRules(kerberosDescriptor, cluster, "EXAMPLE.COM", new HashMap<String, Map<String, String>>(), kerberosConfigurations);
+
+    verifyAll();
+
+    Map<String, String> configs;
+
+    configs = kerberosConfigurations.get("");
+    assertNotNull(configs);
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" +
+        "DEFAULT",
+        configs.get("default"));
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" +
+        "DEFAULT",
+        configs.get("explicit_multiple_lines"));
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\\\n" +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\\\n" +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\\\n" +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\\\n" +
+        "DEFAULT",
+        configs.get("explicit_multiple_lines_escaped"));
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*// " +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/ " +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/ " +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/ " +
+        "DEFAULT",
+        configs.get("explicit_single_line"));
+
+    configs = kerberosConfigurations.get("service-site");
+    assertNotNull(configs);
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" +
+        "DEFAULT",
+        configs.get("default"));
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" +
+        "DEFAULT",
+        configs.get("explicit_multiple_lines"));
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\\\n" +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\\\n" +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\\\n" +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\\\n" +
+        "DEFAULT",
+        configs.get("explicit_multiple_lines_escaped"));
+    assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*// " +
+        "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/ " +
+        "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/ " +
+        "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/ " +
+        "DEFAULT",
+        configs.get("explicit_single_line"));
+  }
+
 
   private void setClusterController() throws Exception {
     KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);