You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ao...@apache.org on 2017/04/01 07:07:55 UTC

[11/17] ambari git commit: AMBARI-20540. Referenced Kerberos identity definitions should be created and distributed only if the referenced service or component is installed

AMBARI-20540. Referenced Kerberos identity definitions should be created and distributed only if the referenced service or component is installed


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

Branch: refs/heads/branch-3.0-perf
Commit: dc05119956a0001001d3edde443612bf42eb9ee0
Parents: d13e6fa
Author: Attila Magyar <am...@hortonworks.com>
Authored: Fri Mar 31 19:37:50 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Sat Apr 1 10:07:36 2017 +0300

----------------------------------------------------------------------
 .../AbstractKerberosDescriptorContainer.java    | 27 ++++++-
 .../kerberos/KerberosIdentityDescriptor.java    | 18 +++++
 .../state/kerberos/KerberosDescriptorTest.java  | 19 +++++
 .../test_filtering_identity_descriptor.json     | 74 ++++++++++++++++++++
 4 files changed, 136 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/dc051199/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
index 73381ee..0a89c1d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
@@ -30,6 +30,13 @@ import java.util.TreeSet;
 import java.util.regex.Pattern;
 
 import org.apache.ambari.server.AmbariException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Sets;
 
 /**
  * AbstractKerberosDescriptorContainer is an abstract class implementing AbstractKerberosDescriptor
@@ -85,6 +92,7 @@ import org.apache.ambari.server.AmbariException;
  * left up to the implementing class to do so.
  */
 public abstract class AbstractKerberosDescriptorContainer extends AbstractKerberosDescriptor {
+  private static final Logger LOG = LoggerFactory.getLogger(AbstractKerberosDescriptorContainer.class);
 
   /**
    * Regular expression pattern used to parse auth_to_local property specifications into the following
@@ -244,14 +252,29 @@ public abstract class AbstractKerberosDescriptorContainer extends AbstractKerber
 
         // Make sure this Kerberos Identity is not to be filtered out based on its "when" clause
         if ((identityToAdd != null) && ((contextForFilter == null) || identityToAdd.shouldInclude(contextForFilter))) {
-          list.add(identityToAdd);
+          if (isReferredServiceInstalled(identity, contextForFilter)) {
+            list.add(identityToAdd);
+          } else {
+            LOG.info("Skipping identity {} because referred service is not installed.", identityToAdd.getName());
+          }
         }
       }
-
       return list;
     }
   }
 
+  private static boolean isReferredServiceInstalled(KerberosIdentityDescriptor identity, Map<String, Object> contextForFilter) {
+    if (contextForFilter == null || !(contextForFilter.get("services") instanceof Collection)) {
+      return true;
+    }
+    Set<String> installedServices = Sets.newHashSet((Collection) contextForFilter.get("services"));
+    return identity.getReferencedServiceName().transform(contains(installedServices)).or(true);
+  }
+
+  private static Function<String, Boolean> contains(final Set<String> installed) {
+    return Functions.forPredicate(Predicates.in(installed));
+  }
+
   /**
    * Return a KerberosIdentityDescriptor with the specified name.
    *

http://git-wip-us.apache.org/repos/asf/ambari/blob/dc051199/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosIdentityDescriptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosIdentityDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosIdentityDescriptor.java
index ae78de6..7c32732 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosIdentityDescriptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosIdentityDescriptor.java
@@ -22,6 +22,8 @@ import java.util.Map;
 import org.apache.ambari.server.collections.Predicate;
 import org.apache.ambari.server.collections.PredicateUtils;
 
+import com.google.common.base.Optional;
+
 /**
  * KerberosIdentityDescriptor is an implementation of an AbstractKerberosDescriptor that
  * encapsulates data related to a Kerberos identity - including its principal and keytab file details.
@@ -351,6 +353,22 @@ public class KerberosIdentityDescriptor extends AbstractKerberosDescriptor {
     return dataMap;
   }
 
+  /***
+   * A name that refers to a service has a format like /[<service name>/[<component name>/]]<identity name>
+   * @return an optional referenced service name
+   */
+  public Optional<String> getReferencedServiceName() {
+    return parseServiceName(reference).or(parseServiceName(getName()));
+  }
+
+  private Optional<String> parseServiceName(String name) {
+    if (name != null && name.startsWith("/") && name.split("/").length > 2) {
+      return Optional.of(name.split("/")[1]);
+    } else {
+      return Optional.absent();
+    }
+  }
+
   @Override
   public int hashCode() {
     return super.hashCode() +

http://git-wip-us.apache.org/repos/asf/ambari/blob/dc051199/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
index f574d99..a63da61 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
@@ -21,7 +21,9 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -30,6 +32,7 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.commons.collections.map.HashedMap;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
@@ -474,4 +477,20 @@ public class KerberosDescriptorTest {
     }
     Assert.assertTrue(identityFound);
   }
+
+  @Test
+  public void testFiltersOutIdentitiesBasedonInstalledServices() throws IOException {
+    URL systemResourceURL = ClassLoader.getSystemResource("kerberos/test_filtering_identity_descriptor.json");
+    KerberosComponentDescriptor componentDescriptor = KERBEROS_DESCRIPTOR_FACTORY.createInstance(new File(systemResourceURL.getFile()))
+      .getService("SERVICE1")
+      .getComponent("SERVICE1_COMPONENT1");
+    List<KerberosIdentityDescriptor> identities = componentDescriptor.getIdentities(true, new HashedMap() {{
+      put("services", Collections.emptySet());
+    }});
+    Assert.assertEquals(0, identities.size());
+    identities = componentDescriptor.getIdentities(true, new HashedMap() {{
+      put("services", Arrays.asList("REF_SERVICE1"));
+    }});
+    Assert.assertEquals(1, identities.size());
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/dc051199/ambari-server/src/test/resources/kerberos/test_filtering_identity_descriptor.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/kerberos/test_filtering_identity_descriptor.json b/ambari-server/src/test/resources/kerberos/test_filtering_identity_descriptor.json
new file mode 100644
index 0000000..40f6101
--- /dev/null
+++ b/ambari-server/src/test/resources/kerberos/test_filtering_identity_descriptor.json
@@ -0,0 +1,74 @@
+{
+  "properties": {
+    "realm": "${kerberos-env/realm}",
+    "keytab_dir": "/etc/security/keytabs"
+  },
+  "services": [
+    {
+      "name": "SERVICE1",
+      "identities": [
+        {
+          "name": "service1_stack_reference",
+          "reference": "/stack_identity",
+          "principal": {
+            "configuration": "service1/property1_principal"
+          },
+          "keytab": {
+            "configuration": "service1/property1_keytab",
+            "file": "${keytab_dir}/service1_stack.keytab"
+          }
+        }
+      ],
+      "components": [
+        {
+          "name": "SERVICE1_COMPONENT1",
+          "identities": [
+            {
+              "name": "component1_service1_stack_reference",
+              "reference": "/REF_SERVICE1/service1_stack_reference",
+              "principal": {
+                "configuration": "component1_service1/property1_principal"
+              },
+              "keytab": {
+                "configuration": "component1_service1/property1_keytab"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "name": "SERVICE2",
+      "identities": [
+        {
+          "name": "service2_stack_reference",
+          "reference": "/stack_identity",
+          "principal": {
+            "configuration": "service2/property1_principal"
+          },
+          "keytab": {
+            "configuration": "service2/property1_keytab",
+            "file": "${keytab_dir}/service2_stack.keytab"
+          }
+        }
+      ],
+      "components": [
+        {
+          "name": "SERVICE2_COMPONENT1",
+          "identities": [
+            {
+              "name": "component1_service2_stack_reference",
+              "reference": "/REF_SERVICE2/REF_SERVICE2_COMPONENT1/service2_stack_reference",
+              "principal": {
+                "configuration": "component1_service2/property1_principal"
+              },
+              "keytab": {
+                "configuration": "component1_service2/property1_keytab"
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}