You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2015/10/23 16:47:41 UTC
[27/50] [abbrv] ambari git commit: AMBARI-13498. Passwords for
components should not be readable by end-users (echekanskiy via dlysnichenko)
AMBARI-13498. Passwords for components should not be readable by end-users (echekanskiy via dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1ff22dff
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1ff22dff
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1ff22dff
Branch: refs/heads/branch-dev-patch-upgrade
Commit: 1ff22dffec728f5df40f41aaf1fa7a5da3f98f35
Parents: 2ff92a9
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Thu Oct 22 19:46:13 2015 +0300
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Thu Oct 22 19:47:32 2015 +0300
----------------------------------------------------------------------
.../AmbariManagementControllerImpl.java | 48 +++++-
.../controller/ConfigurationResponse.java | 43 +++++-
.../org/apache/ambari/server/state/Cluster.java | 19 ++-
.../org/apache/ambari/server/state/Config.java | 4 +
.../apache/ambari/server/state/ConfigImpl.java | 24 +++
.../server/state/cluster/ClusterImpl.java | 60 +++++++-
.../ambari/server/utils/SecretReference.java | 77 ++++++++++
.../AmbariManagementControllerTest.java | 145 +++++++++++++++++++
.../services/HDFS/configuration/hdfs-site.xml | 6 +
9 files changed, 419 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 87e05c6..152016a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -161,6 +161,7 @@ import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEve
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStopEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostUpgradeEvent;
+import org.apache.ambari.server.utils.SecretReference;
import org.apache.ambari.server.utils.StageUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
@@ -719,6 +720,27 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
Cluster cluster = clusters.getCluster(request.getClusterName());
+ Map<String, String> requestProperties = request.getProperties();
+
+ Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes = cluster.getConfigPropertiesTypes(request.getType());
+ if(propertiesTypes.containsKey(PropertyType.PASSWORD)) {
+ for(String passwordProperty : propertiesTypes.get(PropertyType.PASSWORD)) {
+ if(requestProperties.containsKey(passwordProperty)) {
+ String passwordPropertyValue = requestProperties.get(passwordProperty);
+ if (!SecretReference.isSecret(passwordPropertyValue))
+ continue;
+ SecretReference ref = new SecretReference(passwordPropertyValue, passwordProperty, cluster);
+ if (!ref.getClusterName().equals(request.getClusterName()))
+ throw new AmbariException("Can not reference to different cluster in SECRET");
+ String refValue = ref.getValue();
+ requestProperties.put(passwordProperty, refValue);
+ }
+ }
+ }
+
+
+
+
Map<String, Config> configs = cluster.getConfigsByType(
request.getType());
if (null == configs) {
@@ -739,7 +761,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
handleGlobalsBackwardsCompability(request, propertiesAttributes);
- Config config = createConfig(cluster, request.getType(), request.getProperties(),
+ Config config = createConfig(cluster, request.getType(), requestProperties,
request.getVersionTag(), propertiesAttributes);
return new ConfigurationResponse(cluster.getClusterName(), config);
@@ -1215,7 +1237,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
request.getType(),
config.getTag(), entry.getValue().getVersion(),
includeProps ? config.getProperties() : new HashMap<String, String>(),
- includeProps ? config.getPropertiesAttributes() : new HashMap<String, Map<String,String>>());
+ includeProps ? config.getPropertiesAttributes() : new HashMap<String, Map<String,String>>(),
+ config.getPropertiesTypes());
responses.add(response);
}
}
@@ -1228,7 +1251,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
cluster.getClusterName(), config.getStackId(), config.getType(),
config.getTag(), config.getVersion(),
includeProps ? config.getProperties() : new HashMap<String, String>(),
- includeProps ? config.getPropertiesAttributes() : new HashMap<String, Map<String,String>>());
+ includeProps ? config.getPropertiesAttributes() : new HashMap<String, Map<String,String>>(),
+ config.getPropertiesTypes());
responses.add(response);
}
@@ -1365,6 +1389,24 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
if (request.getDesiredConfig() != null) {
for (ConfigurationRequest desiredConfig : request.getDesiredConfig()) {
Map<String, String> requestConfigProperties = desiredConfig.getProperties();
+
+ // processing password properties
+ if(requestConfigProperties != null && !requestConfigProperties.isEmpty()) {
+ Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes = cluster.getConfigPropertiesTypes(
+ desiredConfig.getType()
+ );
+ for (Entry<String, String> property : requestConfigProperties.entrySet()) {
+ String propertyName = property.getKey();
+ String propertyValue = property.getValue();
+ if (propertiesTypes.containsKey(PropertyType.PASSWORD) &&
+ propertiesTypes.get(PropertyType.PASSWORD).contains(propertyName)) {
+ if (SecretReference.isSecret(propertyValue)) {
+ SecretReference ref = new SecretReference(propertyValue, propertyName, cluster);
+ requestConfigProperties.put(propertyName, ref.getValue());
+ }
+ }
+ }
+ }
Map<String,Map<String,String>> requestConfigAttributes = desiredConfig.getPropertiesAttributes();
Config clusterConfig = cluster.getDesiredConfigByType(desiredConfig.getType());
Map<String, String> clusterConfigProperties = null;
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
index d6b95c8..3ed9306 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
@@ -19,9 +19,12 @@ package org.apache.ambari.server.controller;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.utils.SecretReference;
/**
* This class encapsulates a configuration update request.
@@ -46,6 +49,8 @@ public class ConfigurationResponse {
private Map<String, Map<String, String>> configAttributes;
+ private Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes;
+
public ConfigurationResponse(String clusterName, StackId stackId,
String type, String versionTag, Long version,
Map<String, String> configs,
@@ -60,6 +65,23 @@ public class ConfigurationResponse {
this.configAttributes = configAttributes;
}
+ public ConfigurationResponse(String clusterName, StackId stackId,
+ String type, String versionTag, Long version,
+ Map<String, String> configs,
+ Map<String, Map<String, String>> configAttributes,
+ Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes) {
+ this.clusterName = clusterName;
+ this.stackId = stackId;
+ this.configs = configs;
+ this.type = type;
+ this.versionTag = versionTag;
+ this.version = version;
+ this.configs = configs;
+ this.configAttributes = configAttributes;
+ this.propertiesTypes = propertiesTypes;
+ stubPasswords();
+ }
+
/**
* Constructor.
*
@@ -69,7 +91,7 @@ public class ConfigurationResponse {
public ConfigurationResponse(String clusterName, Config config) {
this(clusterName, config.getStackId(), config.getType(), config.getTag(),
config.getVersion(), config.getProperties(),
- config.getPropertiesAttributes());
+ config.getPropertiesAttributes(), config.getPropertiesTypes());
}
/**
@@ -185,4 +207,23 @@ public class ConfigurationResponse {
public void setServiceConfigVersions(List<Long> serviceConfigVersions) {
this.serviceConfigVersions = serviceConfigVersions;
}
+
+ public Map<PropertyInfo.PropertyType, Set<String>> getPropertiesTypes() {
+ return propertiesTypes;
+ }
+
+ public void setPropertiesTypes(Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes) {
+ this.propertiesTypes = propertiesTypes;
+ }
+
+ private void stubPasswords(){
+ if(propertiesTypes != null && propertiesTypes.containsKey(PropertyInfo.PropertyType.PASSWORD)) {
+ for(String pwdPropertyName: propertiesTypes.get(PropertyInfo.PropertyType.PASSWORD)) {
+ if(configs.containsKey(pwdPropertyName)){
+ String stub = SecretReference.generateStub(clusterName, type, version);
+ configs.put(pwdPropertyName, stub);
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
index 0f259d5..f32e552 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
@@ -301,16 +301,33 @@ public interface Cluster {
Map<String, Config> getConfigsByType(String configType);
/**
+ * Gets all properties types that mach the specified type.
+ * @param configType the config type to return
+ * @return properties types for given config type
+ */
+ Map<PropertyInfo.PropertyType, Set<String>> getConfigPropertiesTypes(String configType);
+
+ /**
* Gets the specific config that matches the specified type and tag. This not
* necessarily a DESIRED configuration that applies to a cluster.
* @param configType the config type to find
- * @param versionTag the config version to find
+ * @param versionTag the config version tag to find
* @return a {@link Config} object, or <code>null</code> if the specific type
* and version have not been set.
*/
Config getConfig(String configType, String versionTag);
/**
+ * Gets the specific config that matches the specified type and version. This not
+ * necessarily a DESIRED configuration that applies to a cluster.
+ * @param configType the config type to find
+ * @param configVersion the config version to find
+ * @return a {@link Config} object, or <code>null</code> if the specific type
+ * and version have not been set.
+ */
+ Config getConfigByVersion(String configType, Long configVersion);
+
+ /**
* Sets a specific config. NOTE: This is not a DESIRED configuration that
* applies to a cluster.
* @param config the config instance to add
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java
index e18505a..b35aad9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Config.java
@@ -20,11 +20,15 @@ package org.apache.ambari.server.state;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Represents a single instance of a 'Config Type'
*/
public interface Config {
+ Map<PropertyInfo.PropertyType, Set<String>> getPropertiesTypes();
+
+ void setPropertiesTypes(Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes);
void setStackId(StackId stackId);
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
index ea6aecd..2cc3d00 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
@@ -23,6 +23,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -58,6 +59,7 @@ public class ConfigImpl implements Config {
private volatile Map<String, String> properties;
private volatile Map<String, Map<String, String>> propertiesAttributes;
private ClusterConfigEntity entity;
+ private volatile Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes;
@Inject
private ClusterDAO clusterDAO;
@@ -81,6 +83,7 @@ public class ConfigImpl implements Config {
stackId = cluster.getDesiredStackVersion();
injector.injectMembers(this);
+ propertiesTypes = cluster.getConfigPropertiesTypes(type);
}
@@ -96,6 +99,7 @@ public class ConfigImpl implements Config {
this.entity = entity;
injector.injectMembers(this);
+ propertiesTypes = cluster.getConfigPropertiesTypes(type);
}
/**
@@ -120,6 +124,26 @@ public class ConfigImpl implements Config {
}
@Override
+ public Map<PropertyInfo.PropertyType, Set<String>> getPropertiesTypes() {
+ readWriteLock.readLock().lock();
+ try {
+ return propertiesTypes;
+ } finally {
+ readWriteLock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public void setPropertiesTypes(Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes) {
+ readWriteLock.writeLock().lock();
+ try {
+ this.propertiesTypes = propertiesTypes;
+ } finally {
+ readWriteLock.writeLock().unlock();
+ }
+ }
+
+ @Override
public void setStackId(StackId stackId) {
readWriteLock.writeLock().lock();
try {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index e3bb320..279b31f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -109,6 +109,8 @@ import org.apache.ambari.server.state.ServiceFactory;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
@@ -253,6 +255,8 @@ public class ClusterImpl implements Cluster {
private volatile Multimap<String, String> serviceConfigTypes;
+ private Map<String, Map<PropertyInfo.PropertyType, Set<String>>> configProperiesTypesCache;
+
@Inject
public ClusterImpl(@Assisted ClusterEntity clusterEntity,
Injector injector) throws AmbariException {
@@ -267,6 +271,8 @@ public class ClusterImpl implements Cluster {
desiredStackVersion = new StackId(clusterEntity.getDesiredStack());
+ configProperiesTypesCache = new HashMap<>();
+
cacheConfigurations();
if (desiredStackVersion != null && !StringUtils.isEmpty(desiredStackVersion.getStackName()) && !
@@ -1251,7 +1257,7 @@ public class ClusterImpl implements Cluster {
// Also returns when have a mix of CURRENT and INSTALLING|INSTALLED|UPGRADING|UPGRADED
LOG.warn("have a mix of CURRENT and INSTALLING|INSTALLED|UPGRADING|UPGRADED host versions, " +
- "returning OUT_OF_SYNC as cluster version. Host version states: " + stateToHosts.toString());
+ "returning OUT_OF_SYNC as cluster version. Host version states: " + stateToHosts.toString());
return RepositoryVersionState.OUT_OF_SYNC;
}
@@ -1779,6 +1785,23 @@ public class ClusterImpl implements Cluster {
}
@Override
+ public Config getConfigByVersion(String configType, Long configVersion) {
+ clusterGlobalLock.readLock().lock();
+ try {
+ if (!allConfigs.containsKey(configType)) {
+ return null;
+ }
+ for(Map.Entry<String, Config> entry: allConfigs.get(configType).entrySet()) {
+ if(entry.getValue().getVersion().equals(configVersion))
+ return entry.getValue();
+ }
+ return null;
+ } finally {
+ clusterGlobalLock.readLock().unlock();
+ }
+ }
+
+ @Override
public void addConfig(Config config) {
clusterGlobalLock.writeLock().lock();
try {
@@ -2205,7 +2228,7 @@ public class ClusterImpl implements Cluster {
serviceConfigVersionResponse.getConfigurations().add(
new ConfigurationResponse(getClusterName(), config.getStackId(),
config.getType(), config.getTag(), config.getVersion(),
- config.getProperties(), config.getPropertiesAttributes()));
+ config.getProperties(), config.getPropertiesAttributes(), config.getPropertiesTypes()));
}
serviceConfigVersionResponses.add(serviceConfigVersionResponse);
@@ -2911,6 +2934,39 @@ public class ClusterImpl implements Cluster {
* {@inheritDoc}
*/
@Override
+ public synchronized Map<PropertyInfo.PropertyType, Set<String>> getConfigPropertiesTypes(String configType){
+ if(configProperiesTypesCache.containsKey(configType)) {
+ return configProperiesTypesCache.get(configType);
+ } else {
+ Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes = new HashMap<>();
+ try {
+ StackId stackId = this.getCurrentStackVersion();
+ StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
+ Collection<ServiceInfo> services = stackInfo.getServices();
+ for (ServiceInfo serviceInfo : services) {
+ for (PropertyInfo propertyInfo : serviceInfo.getProperties()) {
+ if (propertyInfo.getFilename().contains(configType) && !propertyInfo.getPropertyTypes().isEmpty()) {
+ Set<PropertyInfo.PropertyType> types = propertyInfo.getPropertyTypes();
+ for (PropertyInfo.PropertyType propertyType : types) {
+ if (!propertiesTypes.containsKey(propertyType))
+ propertiesTypes.put(propertyType, new HashSet<String>());
+ propertiesTypes.get(propertyType).add(propertyInfo.getName());
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+
+ }
+ configProperiesTypesCache.put(configType, propertiesTypes);
+ return propertiesTypes;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
@Transactional
public void removeConfigurations(StackId stackId) {
clusterGlobalLock.writeLock().lock();
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
new file mode 100644
index 0000000..2b1aeae
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.utils;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Config;
+
+import java.util.Map;
+
+public class SecretReference {
+ private String clusterName;
+ private String configType;
+ private Long version;
+ private String value;
+ private String reference;
+
+ public SecretReference(String reference, String propertyName, Cluster cluster) throws AmbariException{
+ String[] values = reference.split(":");
+ clusterName = values[1];
+ configType = values[2];
+ version = Long.valueOf(values[3]);
+ Config refConfig = cluster.getConfigByVersion(configType, version);
+
+ if(refConfig == null)
+ throw new AmbariException(String.format("Cluster: %s does not contain ConfigType: %s ConfigVersion: %s",
+ cluster.getClusterName(), configType, version));
+ Map<String, String> refProperties = refConfig.getProperties();
+ if(!refProperties.containsKey(propertyName))
+ throw new AmbariException(String.format("Cluster: %s ConfigType: %s ConfigVersion: %s does not contain property '%s'",
+ cluster.getClusterName(), configType, version, propertyName));
+ this.value = refProperties.get(propertyName);
+
+ this.reference = reference;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setConfigType(String configType) {
+ this.configType = configType;
+ }
+
+ public Long getVersion() {
+ return version;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static boolean isSecret(String value) {
+ String[] values = value.split(":");
+ return values.length == 4 && values[0].equals("SECRET");
+ }
+
+ public static String generateStub(String clusterName, String configType, Long configVersion) {
+ return "SECRET:" + clusterName + ":" + configType + ":" + configVersion.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 7e2090a..af8c5e2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -10539,6 +10539,151 @@ public class AmbariManagementControllerTest {
}
@Test
+ public void testSecretReferences() throws AmbariException {
+
+ final String host1 = "h1";
+ final String host2 = "h2";
+ Long clusterId = 1L;
+ String clusterName = "foo1";
+ Cluster cl = setupClusterWithHosts(clusterName, "HDP-2.0.5", new ArrayList<String>() {
+ {
+ add(host1);
+ add(host2);
+ }
+ }, "centos5");
+ String serviceName = "HDFS";
+ createService(clusterName, serviceName, null);
+ String componentName1 = "NAMENODE";
+ String componentName2 = "DATANODE";
+ String componentName3 = "HDFS_CLIENT";
+
+ createServiceComponent(clusterName, serviceName, componentName1, State.INIT);
+ createServiceComponent(clusterName, serviceName, componentName2, State.INIT);
+ createServiceComponent(clusterName, serviceName, componentName3, State.INIT);
+
+ createServiceComponentHost(clusterName, serviceName, componentName1, host1, null);
+ createServiceComponentHost(clusterName, serviceName, componentName2, host1, null);
+ createServiceComponentHost(clusterName, serviceName, componentName3, host1, null);
+ createServiceComponentHost(clusterName, serviceName, componentName2, host2, null);
+ createServiceComponentHost(clusterName, serviceName, componentName3, host2, null);
+
+ // Install
+ installService(clusterName, serviceName, false, false);
+
+ ClusterRequest crReq;
+ ConfigurationRequest cr;
+
+ cr = new ConfigurationRequest(clusterName,
+ "hdfs-site",
+ "version1",
+ new HashMap<String, String>(){{
+ put("test.password", "first");
+ }},
+ new HashMap<String, Map<String, String>>()
+ );
+ crReq = new ClusterRequest(clusterId, clusterName, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr));
+ controller.updateClusters(Collections.singleton(crReq), null);
+ // update config with secret reference
+ cr = new ConfigurationRequest(clusterName,
+ "hdfs-site",
+ "version2",
+ new HashMap<String, String>(){{
+ put("test.password", "SECRET:c1:hdfs-site:1");
+ put("new", "new");//need this to mark config as "changed"
+ }},
+ new HashMap<String, Map<String, String>>()
+ );
+ crReq = new ClusterRequest(clusterId, clusterName, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr));
+ controller.updateClusters(Collections.singleton(crReq), null);
+ // change password to new value
+ cr = new ConfigurationRequest(clusterName,
+ "hdfs-site",
+ "version3",
+ new HashMap<String, String>(){{
+ put("test.password", "brandNewPassword");
+ }},
+ new HashMap<String, Map<String, String>>()
+ );
+ crReq = new ClusterRequest(clusterId, clusterName, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr));
+ controller.updateClusters(Collections.singleton(crReq), null);
+ // wrong secret reference
+ cr = new ConfigurationRequest(clusterName,
+ "hdfs-site",
+ "version3",
+ new HashMap<String, String>(){{
+ put("test.password", "SECRET:c1:hdfs-site:666");
+ }},
+ new HashMap<String, Map<String, String>>()
+ );
+ crReq = new ClusterRequest(clusterId, clusterName, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr));
+ try {
+ controller.updateClusters(Collections.singleton(crReq), null);
+ fail("Request need to be failed with wrong secret reference");
+ } catch (AmbariException e){
+
+ }
+ // reference to config which does not contain requested property
+ cr = new ConfigurationRequest(clusterName,
+ "hdfs-site",
+ "version4",
+ new HashMap<String, String>(){{
+ put("foo", "bar");
+ }},
+ new HashMap<String, Map<String, String>>()
+ );
+ crReq = new ClusterRequest(clusterId, clusterName, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr));
+ controller.updateClusters(Collections.singleton(crReq), null);
+ cr = new ConfigurationRequest(clusterName,
+ "hdfs-site",
+ "version5",
+ new HashMap<String, String>(){{
+ put("test.password", "SECRET:c1:hdfs-site:4");
+ put("new", "new");
+ }},
+ new HashMap<String, Map<String, String>>()
+ );
+ crReq = new ClusterRequest(clusterId, clusterName, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr));
+ try {
+ controller.updateClusters(Collections.singleton(crReq), null);
+ fail("Request need to be failed with wrong secret reference");
+ } catch (AmbariException e) {
+ assertEquals("Cluster: foo1 ConfigType: hdfs-site ConfigVersion: 4 does not contain property 'test.password'",
+ e.getMessage());
+ }
+ cl.getAllConfigs();
+ assertEquals(cl.getAllConfigs().size(), 4);
+
+ Config v1 = cl.getConfigByVersion("hdfs-site", 1l);
+ Config v2 = cl.getConfigByVersion("hdfs-site", 2l);
+ Config v3 = cl.getConfigByVersion("hdfs-site", 3l);
+ Config v4 = cl.getConfigByVersion("hdfs-site", 4l);
+
+ assertEquals(v1.getProperties().get("test.password"), "first");
+ assertEquals(v2.getProperties().get("test.password"), "first");
+ assertEquals(v3.getProperties().get("test.password"), "brandNewPassword");
+ assertFalse(v4.getProperties().containsKey("test.password"));
+
+ // check if we have masked secret in responce
+ final ConfigurationRequest configRequest = new ConfigurationRequest(clusterName, "hdfs-site", null, null, null);
+ configRequest.setIncludeProperties(true);
+ Set<ConfigurationResponse> requestedConfigs = controller.getConfigurations(new HashSet<ConfigurationRequest>() {{
+ add(configRequest);
+ }});
+ for(ConfigurationResponse resp : requestedConfigs) {
+ String secretName = "SECRET:foo1:hdfs-site:"+resp.getVersion().toString();
+ if(resp.getConfigs().containsKey("test.password")) {
+ assertEquals(resp.getConfigs().get("test.password"), secretName);
+ }
+ }
+ }
+
+ @Test
public void testTargetedProcessCommand() throws Exception {
final String host1 = "h1";
String clusterName = "c1";
http://git-wip-us.apache.org/repos/asf/ambari/blob/1ff22dff/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
index 246b2f9..f53c667 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/configuration/hdfs-site.xml
@@ -23,6 +23,12 @@
<configuration>
<!-- file system properties -->
+ <property>
+ <name>test.password</name>
+ <property-type>PASSWORD</property-type>
+ <value>test</value>
+ <description>1</description>
+ </property>
<property>
<name>dfs.namenode.name.dir</name>