You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rn...@apache.org on 2015/05/15 17:12:04 UTC
ambari git commit: AMBARI-9480. Ranger password properties are
incorrectly included in Blueprint export. (rnettleton)
Repository: ambari
Updated Branches:
refs/heads/trunk 0fe39d5e8 -> 46c802dae
AMBARI-9480. Ranger password properties are incorrectly included in Blueprint export. (rnettleton)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/46c802da
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/46c802da
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/46c802da
Branch: refs/heads/trunk
Commit: 46c802daed7ec886da1a678fba4ab361b2800e3d
Parents: 0fe39d5
Author: Bob Nettleton <rn...@hortonworks.com>
Authored: Fri May 15 11:10:42 2015 -0400
Committer: Bob Nettleton <rn...@hortonworks.com>
Committed: Fri May 15 11:11:51 2015 -0400
----------------------------------------------------------------------
.../BlueprintConfigurationProcessor.java | 118 +++++++++++++++++++
.../BlueprintConfigurationProcessorTest.java | 82 +++++++++++++
2 files changed, 200 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/46c802da/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
index aef6664..d7ff543 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
@@ -106,6 +106,13 @@ public class BlueprintConfigurationProcessor {
new HashSet<String>(Arrays.asList("fs.defaultFS", "hbase.rootdir", "instance.volumes"));
/**
+ * Statically-defined list of filters to apply on property exports.
+ * This will initially be used to filter out the Ranger Passwords, but
+ * could be extended in the future for more generic purposes.
+ */
+ private static final PropertyFilter[] propertyFilters = { new PasswordPropertyFilter() };
+
+ /**
* Configuration properties to be updated
*/
//private Map<String, Map<String, String>> properties;
@@ -233,6 +240,39 @@ public class BlueprintConfigurationProcessor {
doMultiHostExportUpdate(multiHostTopologyUpdaters, properties);
doRemovePropertyExport(removePropertyUpdaters, properties);
+
+ doFilterPriorToExport(properties);
+ }
+ }
+
+ /**
+ * This method iterates over the properties passed in, and applies a
+ * list of filters to the properties.
+ *
+ * If any filter implementations indicate that the property should
+ * not be included in a collection (a Blueprint export in this case),
+ * then the property is removed prior to the export.
+ *
+ *
+ * @param properties config properties to process for filtering
+ */
+ private static void doFilterPriorToExport(Map<String, Map<String, String>> properties) {
+ for (String configType : properties.keySet()) {
+ Map<String, String> configPropertiesPerType =
+ properties.get(configType);
+
+ Set<String> propertiesToExclude = new HashSet<String>();
+ for (String propertyName : configPropertiesPerType.keySet()) {
+ if (shouldPropertyBeExcluded(propertyName, configPropertiesPerType.get(propertyName))) {
+ propertiesToExclude.add(propertyName);
+ }
+ }
+
+ if (!propertiesToExclude.isEmpty()) {
+ for (String propertyName : propertiesToExclude) {
+ configPropertiesPerType.remove(propertyName);
+ }
+ }
}
}
@@ -435,6 +475,29 @@ public class BlueprintConfigurationProcessor {
}
/**
+ * Iterates over the list of registered filters for this config processor, and
+ * queries each filter to determine if a given property should be included
+ * in a property collection. If any filters return false for the isPropertyIncluded()
+ * query, then the property should be excluded.
+ *
+ * @param propertyName config property name
+ * @param propertyValue config property value
+ * @return true if the property should be excluded
+ * false if the property should not be excluded
+ */
+ private static boolean shouldPropertyBeExcluded(String propertyName, String propertyValue) {
+ for(PropertyFilter filter : propertyFilters) {
+ if (!filter.isPropertyIncluded(propertyName, propertyValue)) {
+ return true;
+ }
+ }
+
+ // if no filters require that the property be excluded,
+ // then allow it to be included in the property collection
+ return false;
+ }
+
+ /**
* Update single host topology configuration properties for blueprint export.
*
* @param updaters registered updaters
@@ -1790,4 +1853,59 @@ public class BlueprintConfigurationProcessor {
properties.put(property, defaultValue);
}
}
+
+
+ /**
+ * Defines an interface for querying a filter to determine
+ * if a given property should be included in an external
+ * collection of properties.
+ */
+ private static interface PropertyFilter {
+
+ /**
+ * Query to determine if a given property should be included in a collection of
+ * properties.
+ *
+ * @param propertyName property name
+ * @param propertyValue property value
+ * @return true if the property should be included
+ * false if the property should not be included
+ */
+ boolean isPropertyIncluded(String propertyName, String propertyValue);
+ }
+
+ /**
+ * A Filter that excludes properties if the property name matches
+ * a pattern of "*PASSWORD" (case-insensitive).
+ *
+ */
+ private static class PasswordPropertyFilter implements PropertyFilter {
+
+ private static final Pattern PASSWORD_NAME_REGEX = Pattern.compile("\\S+PASSWORD", Pattern.CASE_INSENSITIVE);
+
+ /**
+ * Query to determine if a given property should be included in a collection of
+ * properties.
+ *
+ * This implementation uses a regular expression to determine if
+ * a given property name ends with "PASSWORD", using a case-insensitive match.
+ * This will be used to filter out Ranger passwords that are not considered "required"
+ * passwords by the stack metadata. This could potentially also
+ * be useful in filtering out properties that are added to
+ * stacks, but not directly marked as the PASSWORD type, even if they
+ * are indeed passwords.
+ *
+ *
+ * @param propertyName property name
+ * @param propertyValue property value
+ *
+ * @return true if the property should be included
+ * false if the property should not be included
+ */
+ @Override
+ public boolean isPropertyIncluded(String propertyName, String propertyValue) {
+ return !PASSWORD_NAME_REGEX.matcher(propertyName).matches();
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46c802da/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
index 390f73e..bebc884 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
@@ -456,6 +456,88 @@ public class BlueprintConfigurationProcessorTest {
}
@Test
+ public void testDoUpdateForBlueprintExport_PasswordFilterApplied() throws Exception {
+ Map<String, Map<String, String>> properties = new HashMap<String, Map<String, String>>();
+ Map<String, String> typeProps = new HashMap<String, String>();
+ typeProps.put("REPOSITORY_CONFIG_PASSWORD", "test-password-one");
+ typeProps.put("SSL_KEYSTORE_PASSWORD", "test-password-two");
+ typeProps.put("SSL_TRUSTSTORE_PASSWORD", "test-password-three");
+ typeProps.put("XAAUDIT.DB.PASSWORD", "test-password-four");
+ typeProps.put("test.ssl.password", "test-password-five");
+ typeProps.put("test.password.should.be.included", "test-another-pwd");
+
+ // create a custom config type, to verify that the filters can
+ // be applied across all config types
+ Map<String, String> customProps = new HashMap<String, String>();
+ customProps.put("my_test_PASSWORD", "should be excluded");
+ customProps.put("PASSWORD_mytest", "should be included");
+
+ properties.put("ranger-yarn-plugin-properties", typeProps);
+ properties.put("custom-test-properties", customProps);
+
+ Configuration clusterConfig = new Configuration(properties,
+ Collections.<String, Map<String, Map<String, String>>>emptyMap());
+
+ Collection<String> hgComponents = new HashSet<String>();
+ hgComponents.add("NAMENODE");
+ hgComponents.add("SECONDARY_NAMENODE");
+ hgComponents.add("RESOURCEMANAGER");
+ TestHostGroup group1 = new TestHostGroup("group1", hgComponents, Collections.singleton("testhost"));
+
+ Collection<String> hgComponents2 = new HashSet<String>();
+ hgComponents2.add("DATANODE");
+ hgComponents2.add("HDFS_CLIENT");
+ TestHostGroup group2 = new TestHostGroup("group2", hgComponents2, Collections.singleton("testhost2"));
+
+ Collection<TestHostGroup> hostGroups = new HashSet<TestHostGroup>();
+ hostGroups.add(group1);
+ hostGroups.add(group2);
+
+ ClusterTopology topology = createClusterTopology(bp, clusterConfig, hostGroups);
+ BlueprintConfigurationProcessor configProcessor = new BlueprintConfigurationProcessor(topology);
+ configProcessor.doUpdateForBlueprintExport();
+
+
+ assertEquals("Exported properties map was not of the expected size",
+ 1,typeProps.size());
+ assertEquals("ranger-yarn-plugin-properties config type was not properly exported",
+ 1, properties.get("ranger-yarn-plugin-properties").size());
+
+ // verify that the following password properties matching the "*_PASSWORD" rule have been excluded
+ assertFalse("Password property should have been excluded",
+ properties.get("ranger-yarn-plugin-properties").containsKey("REPOSITORY_CONFIG_PASSWORD"));
+ assertFalse("Password property should have been excluded",
+ properties.get("ranger-yarn-plugin-properties").containsKey("SSL_KEYSTORE_PASSWORD"));
+ assertFalse("Password property should have been excluded",
+ properties.get("ranger-yarn-plugin-properties").containsKey("SSL_TRUSTSTORE_PASSWORD"));
+ assertFalse("Password property should have been excluded",
+ properties.get("ranger-yarn-plugin-properties").containsKey("XAAUDIT.DB.PASSWORD"));
+ assertFalse("Password property should have been excluded",
+ properties.get("ranger-yarn-plugin-properties").containsKey("test.ssl.password"));
+
+
+ // verify that the property that does not match the "*_PASSWORD" rule is still included
+ assertTrue("Expected password property not found",
+ properties.get("ranger-yarn-plugin-properties").containsKey("test.password.should.be.included"));
+
+ // verify the custom properties map has been modified by the filters
+ assertEquals("custom-test-properties type was not properly exported",
+ 1, properties.get("custom-test-properties").size());
+
+ // verify that the following password properties matching the "*_PASSWORD" rule have been excluded
+ assertFalse("Password property should have been excluded",
+ properties.get("custom-test-properties").containsKey("my_test_PASSWORD"));
+
+ // verify that the property that does not match the "*_PASSWORD" rule is still included
+ assertTrue("Expected password property not found",
+ properties.get("custom-test-properties").containsKey("PASSWORD_mytest"));
+ assertEquals("Expected password property should not have been modified",
+ "should be included", properties.get("custom-test-properties").get("PASSWORD_mytest"));
+
+ }
+
+
+ @Test
public void testFalconConfigExport() throws Exception {
final String expectedHostName = "c6401.apache.ambari.org";
final String expectedPortNum = "808080";