Переглянути джерело

AMBARI-16223. Ambari server principal and keytab missing from generated CSV file. (magyari_sandor)

Sandor Magyari 9 роки тому
батько
коміт
4b2de80ba2

+ 35 - 5
ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java

@@ -1248,6 +1248,7 @@ public class KerberosHelperImpl implements KerberosHelper {
     Map<String, Collection<KerberosIdentityDescriptor>> activeIdentities = new HashMap<String, Collection<KerberosIdentityDescriptor>>();
 
     Collection<String> hosts;
+    String ambariServerHostname = StageUtils.getHostName();
 
     if (hostName == null) {
       Map<String, Host> hostMap = clusters.getHostsForCluster(clusterName);
@@ -1256,24 +1257,39 @@ public class KerberosHelperImpl implements KerberosHelper {
       } else {
         hosts = hostMap.keySet();
       }
+
+      if (!hosts.contains(ambariServerHostname)) {
+        Collection<String> extendedHosts = new ArrayList<>(hosts.size() + 1);
+        extendedHosts.addAll(hosts);
+        extendedHosts.add(ambariServerHostname);
+        hosts = extendedHosts;
+      }
     } else {
       hosts = Collections.singleton(hostName);
     }
 
+    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster);
+
     if ((hosts != null) && !hosts.isEmpty()) {
-      KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster);
 
       if (kerberosDescriptor != null) {
         Map<String, String> kerberosDescriptorProperties = kerberosDescriptor.getProperties();
 
         for (String hostname : hosts) {
           Map<String, KerberosIdentityDescriptor> hostActiveIdentities = new HashMap<String, KerberosIdentityDescriptor>();
-          List<KerberosIdentityDescriptor> identities = getActiveIdentities(cluster, hostname, serviceName, componentName, kerberosDescriptor);
+          List<KerberosIdentityDescriptor> identities = getActiveIdentities(cluster, hostname,
+            serviceName, componentName, kerberosDescriptor);
+
+          if (hostname.equals(ambariServerHostname)) {
+            addAmbariServerIdentity(cluster, kerberosDescriptor, identities);
+          }
 
           if (!identities.isEmpty()) {
             // Calculate the current host-specific configurations. These will be used to replace
             // variables within the Kerberos descriptor data
-            Map<String, Map<String, String>> configurations = calculateConfigurations(cluster, hostname, kerberosDescriptorProperties);
+            Map<String, Map<String, String>> configurations = calculateConfigurations(cluster, hostname.equals
+                (ambariServerHostname) ? null : hostname,
+              kerberosDescriptorProperties);
 
             for (KerberosIdentityDescriptor identity : identities) {
               KerberosPrincipalDescriptor principalDescriptor = identity.getPrincipalDescriptor();
@@ -1344,6 +1360,21 @@ public class KerberosHelperImpl implements KerberosHelper {
     return activeIdentities;
   }
 
+  private void addAmbariServerIdentity(Cluster cluster, KerberosDescriptor kerberosDescriptor, List<KerberosIdentityDescriptor> identities) throws AmbariException {
+    try {
+      KerberosDetails kerberosDetails = getKerberosDetails(cluster, null);
+      // append Ambari server principal
+      if (kerberosDetails.createAmbariPrincipal()) {
+        KerberosIdentityDescriptor ambariServerIdentity = kerberosDescriptor.getIdentity(KerberosHelper.AMBARI_IDENTITY_NAME);
+        if (ambariServerIdentity != null) {
+          identities.add(ambariServerIdentity);
+        }
+      }
+    } catch (KerberosInvalidConfigurationException e) {
+      LOG.warn("Unable to append Ambari server principal: {}", e);
+    }
+  }
+
   /**
    * Gets the previously stored KDC administrator credential.
    * <p/>
@@ -2255,8 +2286,7 @@ public class KerberosHelperImpl implements KerberosHelper {
    *                           services
    * @param componentName      the name of a component for which to find results, null indicates all
    *                           components
-   * @param kerberosDescriptor the relevant Kerberos Descriptor
-   * @return a list of KerberosIdentityDescriptors representing the active identities for the
+   * @param kerberosDescriptor the relevant Kerberos Descriptor     @return a list of KerberosIdentityDescriptors representing the active identities for the
    * requested service component
    * @throws AmbariException if an error occurs processing the cluster's active identities
    */

+ 25 - 17
ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIndetityServerAction.java

@@ -198,28 +198,36 @@ public class ConfigureAmbariIndetityServerAction extends KerberosServerAction {
 
   private void configureJAAS(String evaluatedPrincipal, String keytabFilePath, ActionLog actionLog) {
     String jaasConfPath = System.getProperty(KerberosChecker.JAVA_SECURITY_AUTH_LOGIN_CONFIG);
-    File jaasConfigFile = new File(jaasConfPath);
-    try {
-      String jaasConfig = FileUtils.readFileToString(jaasConfigFile);
-      File oldJaasConfigFile = new File(jaasConfPath + ".bak");
-      FileUtils.writeStringToFile(oldJaasConfigFile, jaasConfig);
-      jaasConfig = jaasConfig.replaceFirst(KEYTAB_PATTERN, "keyTab=\"" + keytabFilePath + "\"");
-      jaasConfig = jaasConfig.replaceFirst(PRINCIPAL_PATTERN, "principal=\"" + evaluatedPrincipal + "\"");
-      FileUtils.writeStringToFile(jaasConfigFile, jaasConfig);
-      String message = String.format("JAAS config file %s modified successfully for principal %s.", jaasConfigFile
-        .getName(), evaluatedPrincipal);
-      if (actionLog != null) {
-        actionLog.writeStdOut(message);
+    if (jaasConfPath != null) {
+      File jaasConfigFile = new File(jaasConfPath);
+      try {
+        String jaasConfig = FileUtils.readFileToString(jaasConfigFile);
+        File oldJaasConfigFile = new File(jaasConfPath + ".bak");
+        FileUtils.writeStringToFile(oldJaasConfigFile, jaasConfig);
+        jaasConfig = jaasConfig.replaceFirst(KEYTAB_PATTERN, "keyTab=\"" + keytabFilePath + "\"");
+        jaasConfig = jaasConfig.replaceFirst(PRINCIPAL_PATTERN, "principal=\"" + evaluatedPrincipal + "\"");
+        FileUtils.writeStringToFile(jaasConfigFile, jaasConfig);
+        String message = String.format("JAAS config file %s modified successfully for principal %s.", jaasConfigFile
+          .getName(), evaluatedPrincipal);
+        if (actionLog != null) {
+          actionLog.writeStdOut(message);
+        }
+      } catch (IOException e) {
+        String message = String.format("Failed to configure JAAS file %s for %s - %s", jaasConfigFile,
+          evaluatedPrincipal, e.getMessage());
+        if (actionLog != null) {
+          actionLog.writeStdErr(message);
+        }
+        LOG.error(message, e);
       }
-    } catch (IOException e) {
-      String message = String.format("Failed to configure JAAS file %s for %s - %s", jaasConfigFile,
-        evaluatedPrincipal, e.getMessage());
+    } else {
+      String message = String.format("Failed to configure JAAS, config file should be passed to Ambari server as: " +
+        "%s.", KerberosChecker.JAVA_SECURITY_AUTH_LOGIN_CONFIG);
       if (actionLog != null) {
         actionLog.writeStdErr(message);
       }
-      LOG.error(message, e);
+      LOG.error(message);
     }
-
   }
 
   /**

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/kerberos.json

@@ -47,7 +47,7 @@
     {
       "name": "ambari-server",
       "principal": {
-        "value": "ambari-server-${cluster_name}@${realm}",
+        "value": "ambari-server-${cluster_name|toLower()}@${realm}",
         "type" : "user",
         "configuration": "cluster-env/ambari_principal_name"
       },

+ 33 - 3
ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java

@@ -101,6 +101,7 @@ import org.junit.Test;
 
 import javax.persistence.EntityManager;
 import java.lang.reflect.Field;
+import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -567,7 +568,7 @@ public class KerberosHelperTest extends EasyMockSupport {
     Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", null, "SERVICE1", null, true, SecurityType.KERBEROS);
 
     Assert.assertNotNull(identities);
-    Assert.assertEquals(2, identities.size());
+    Assert.assertEquals(3, identities.size());
 
     Collection<KerberosIdentityDescriptor> hostIdentities;
 
@@ -701,7 +702,7 @@ public class KerberosHelperTest extends EasyMockSupport {
     Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", null, null, "COMPONENT2", true, SecurityType.KERBEROS);
 
     Assert.assertNotNull(identities);
-    Assert.assertEquals(2, identities.size());
+    Assert.assertEquals(3, identities.size());
 
     Collection<KerberosIdentityDescriptor> hostIdentities;
 
@@ -754,7 +755,7 @@ public class KerberosHelperTest extends EasyMockSupport {
     Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", null, null, null, true, clusterSecurityType);
 
     Assert.assertNotNull(identities);
-    Assert.assertEquals(2, identities.size());
+    Assert.assertEquals(3, identities.size());
 
     Collection<KerberosIdentityDescriptor> hostIdentities;
 
@@ -3673,6 +3674,35 @@ public class KerberosHelperTest extends EasyMockSupport {
           }
         })
         .anyTimes();
+    expect(cluster.getServiceComponentHosts(InetAddress.getLocalHost().getCanonicalHostName().toLowerCase()))
+      .andReturn(new ArrayList<ServiceComponentHost>())
+      .anyTimes();
+
+    final Map<String, String> kerberosEnvProperties = new HashMap<String, String>() {
+      {
+        put("kdc_type", "mit-kdc");
+        put("realm", "FOOBAR.COM");
+        put("case_insensitive_username_rules", "false");
+        put("create_ambari_principal", "false");
+      }
+    };
+
+    final Config kerberosEnvConfig = createMock(Config.class);
+    expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes();
+
+    final Map<String, String> krb5ConfProperties = createMock(Map.class);
+
+    final Config krb5ConfConfig = createMock(Config.class);
+    expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes();
+
+    expect(cluster.getDesiredConfigByType("krb5-conf"))
+      .andReturn(krb5ConfConfig)
+      .anyTimes();
+
+    expect(cluster.getDesiredConfigByType("kerberos-env"))
+      .andReturn(kerberosEnvConfig)
+      .anyTimes();
+
     expect(cluster.getCurrentStackVersion())
         .andReturn(new StackId("HDP", "2.2"))
         .anyTimes();