You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sm...@apache.org on 2017/02/24 16:42:34 UTC
ambari git commit: AMBARI-20034. USER to GROUP mapping (hdfs_user ->
hadoop_group) should be stack driven (Madhuvanthi Radhakrishnan via smohanty)
Repository: ambari
Updated Branches:
refs/heads/branch-2.5 7702c4714 -> b856c5f37
AMBARI-20034. USER to GROUP mapping (hdfs_user -> hadoop_group) should be stack driven (Madhuvanthi Radhakrishnan via smohanty)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b856c5f3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b856c5f3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b856c5f3
Branch: refs/heads/branch-2.5
Commit: b856c5f37c0573d4231b1976ad1523425947e2f8
Parents: 7702c47
Author: Sumit Mohanty <sm...@hortonworks.com>
Authored: Fri Feb 24 08:42:18 2017 -0800
Committer: Sumit Mohanty <sm...@hortonworks.com>
Committed: Fri Feb 24 08:42:18 2017 -0800
----------------------------------------------------------------------
.../ambari/server/agent/ExecutionCommand.java | 1 +
.../AmbariCustomCommandExecutionHelper.java | 7 +
.../AmbariManagementControllerImpl.java | 7 +
.../internal/ClientConfigResourceProvider.java | 7 +
.../ambari/server/state/ConfigHelper.java | 168 +++++++++++++++++++
.../ambari/server/state/PropertyInfo.java | 4 +
.../apache/ambari/server/state/ServiceInfo.java | 5 +
.../ambari/server/state/UserGroupInfo.java | 50 ++++++
.../server/state/ValueAttributesInfo.java | 15 ++
.../src/main/resources/configuration-schema.xsd | 17 ++
.../2.0.6/hooks/before-ANY/scripts/params.py | 9 +-
.../server/api/services/AmbariMetaInfoTest.java | 2 +-
.../AmbariCustomCommandExecutionHelperTest.java | 66 +++++++-
.../AmbariManagementControllerTest.java | 23 ++-
.../ClientConfigResourceProviderTest.java | 54 +++++-
.../ambari/server/stack/StackManagerTest.java | 2 +-
.../python/stacks/2.0.6/configs/default.json | 1 +
.../services/HDFS/configuration/hadoop-env.xml | 53 ++++++
18 files changed, 468 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 5c4f08e..c80ebe6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -429,6 +429,7 @@ public class ExecutionCommand extends AgentCommand {
String COMPONENT_CATEGORY = "component_category";
String USER_LIST = "user_list";
String GROUP_LIST = "group_list";
+ String USER_GROUPS = "user_groups";
String NOT_MANAGED_HDFS_PATH_LIST = "not_managed_hdfs_path_list";
String VERSION = "version";
String REFRESH_TOPOLOGY = "refresh_topology";
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index b601893..867ebff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -43,6 +43,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TY
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_GROUPS;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
import java.text.MessageFormat;
@@ -413,6 +414,12 @@ public class AmbariCustomCommandExecutionHelper {
String userList = gson.toJson(userSet);
hostLevelParams.put(USER_LIST, userList);
+ //Create a user_group mapping and send it as part of the hostLevelParams
+ Map<String, Set<String>> userGroupsMap = configHelper.createUserGroupsMap(
+ stackId, cluster, desiredConfigs);
+ String userGroups = gson.toJson(userGroupsMap);
+ hostLevelParams.put(USER_GROUPS, userGroups);
+
Set<String> groupSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.GROUP, cluster, desiredConfigs);
String groupList = gson.toJson(groupSet);
hostLevelParams.put(GROUP_LIST, groupList);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/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 3b88ac9..c25ab97 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
@@ -39,6 +39,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_GROUPS;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
@@ -2404,6 +2405,12 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
String userList = gson.toJson(userSet);
hostParams.put(USER_LIST, userList);
+ //Create a user_group mapping and send it as part of the hostLevelParams
+ Map<String, Set<String>> userGroupsMap = configHelper.createUserGroupsMap(
+ cluster, clusterDesiredConfigs, servicesMap, stackProperties);
+ String userGroups = gson.toJson(userGroupsMap);
+ hostParams.put(USER_GROUPS, userGroups);
+
Set<String> groupSet = configHelper.getPropertyValuesWithPropertyType(PropertyType.GROUP, cluster, clusterDesiredConfigs, servicesMap, stackProperties);
String groupList = gson.toJson(groupSet);
hostParams.put(GROUP_LIST, groupList);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
index 8a35c98..42e9b34 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
@@ -35,6 +35,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_L
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_GROUPS;
import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
import java.io.BufferedInputStream;
@@ -396,6 +397,12 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv
String userList = gson.toJson(userSet);
hostLevelParams.put(USER_LIST, userList);
+ //Create a user_group mapping and send it as part of the hostLevelParams
+ Map<String, Set<String>> userGroupsMap = configHelper.createUserGroupsMap(
+ stackId, cluster, desiredClusterConfigs);
+ String userGroups = gson.toJson(userGroupsMap);
+ hostLevelParams.put(USER_GROUPS,userGroups);
+
Set<String> groupSet = configHelper.getPropertyValuesWithPropertyType(stackId, PropertyType.GROUP, cluster, desiredClusterConfigs);
String groupList = gson.toJson(groupSet);
hostLevelParams.put(GROUP_LIST, groupList);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
index 978ecd7..13114dd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
@@ -545,6 +545,156 @@ public class ConfigHelper {
return result;
}
+ /***
+ * Fetch user to group mapping from the cluster configs. UserGroupEntries contain information regarding the group that the user is associated to.
+ * @param stackId
+ * @param cluster
+ * @param desiredConfigs
+ * @return
+ * @throws AmbariException
+ */
+ public Map<String, Set<String>> createUserGroupsMap(StackId stackId,
+ Cluster cluster, Map<String, DesiredConfig> desiredConfigs) throws AmbariException {
+ StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
+ Map<String, ServiceInfo> servicesMap = ambariMetaInfo.getServices(stack.getName(), stack.getVersion());
+ Set<PropertyInfo> stackProperties = ambariMetaInfo.getStackProperties(stack.getName(), stack.getVersion());
+ return createUserGroupsMap(cluster, desiredConfigs, servicesMap, stackProperties);
+ }
+
+ /***
+ * Fetch user to group mapping from the cluster configs. UserGroupEntries contain information regarding the group that the user is associated to.
+ * @param cluster
+ * @param desiredConfigs
+ * @param servicesMap
+ * @param stackProperties
+ * @return
+ * @throws AmbariException
+ */
+ public Map<String, Set<String>> createUserGroupsMap(
+ Cluster cluster, Map<String, DesiredConfig> desiredConfigs,
+ Map<String, ServiceInfo> servicesMap, Set<PropertyInfo> stackProperties) throws AmbariException {
+
+ Map<String, Set<String>> userGroupsMap = new HashMap<>();
+ Map<PropertyInfo, String> userProperties = getPropertiesWithPropertyType(
+ PropertyType.USER, cluster, desiredConfigs, servicesMap, stackProperties);
+ Map<PropertyInfo, String> groupProperties = getPropertiesWithPropertyType(
+ PropertyType.GROUP, cluster, desiredConfigs, servicesMap, stackProperties);
+
+ if(userProperties != null && groupProperties != null) {
+ for(Map.Entry<PropertyInfo, String> userProperty : userProperties.entrySet()) {
+ PropertyInfo userPropertyInfo = userProperty.getKey();
+ String userPropertyValue = userProperty.getValue();
+ if(userPropertyInfo.getPropertyValueAttributes() != null
+ && userPropertyInfo.getPropertyValueAttributes().getUserGroupEntries() != null) {
+ Set<String> groupPropertyValues = new HashSet<>();
+ Collection<UserGroupInfo> userGroupEntries = userPropertyInfo.getPropertyValueAttributes().getUserGroupEntries();
+ for (UserGroupInfo userGroupInfo : userGroupEntries) {
+ boolean found = false;
+ for(Map.Entry<PropertyInfo, String> groupProperty : groupProperties.entrySet()) {
+ PropertyInfo groupPropertyInfo = groupProperty.getKey();
+ String groupPropertyValue = groupProperty.getValue();
+ if(StringUtils.equals(userGroupInfo.getType(),
+ ConfigHelper.fileNameToConfigType(groupPropertyInfo.getFilename()))
+ && StringUtils.equals(userGroupInfo.getName(), groupPropertyInfo.getName())) {
+ groupPropertyValues.add(groupPropertyValue);
+ found = true;
+ }
+ }
+ if(!found) {
+ //Log error if the user-group mapping is not found
+ LOG.error("User group mapping property {" + userGroupInfo.getType() + "/" + userGroupInfo.getName() + "} is missing for user property {" + ConfigHelper.fileNameToConfigType(userPropertyInfo.getFilename()) + "/" + userPropertyInfo.getName() + "} (username = " + userPropertyInfo.getValue() +")");
+ }
+ }
+ userGroupsMap.put(userPropertyValue, groupPropertyValues);
+ }
+ }
+ }
+ return userGroupsMap;
+ }
+
+ /***
+ * Fetch all the properties of a given PropertyType. For eg: Fetch all cluster configs that are of type "user"
+ * @param stackId
+ * @param propertyType
+ * @param cluster
+ * @param desiredConfigs
+ * @return
+ * @throws AmbariException
+ */
+ public Map<PropertyInfo, String> getPropertiesWithPropertyType(StackId stackId, PropertyType propertyType,
+ Cluster cluster, Map<String, DesiredConfig> desiredConfigs) throws AmbariException {
+ StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
+ Map<String, ServiceInfo> servicesMap = ambariMetaInfo.getServices(stack.getName(), stack.getVersion());
+ Set<PropertyInfo> stackProperties = ambariMetaInfo.getStackProperties(stack.getName(), stack.getVersion());
+
+ return getPropertiesWithPropertyType(propertyType, cluster, desiredConfigs, servicesMap, stackProperties);
+ }
+
+ /***
+ * Fetch all the properties of a given PropertyType. For eg: Fetch all cluster configs that are of type "user"
+ * @param propertyType
+ * @param cluster
+ * @param desiredConfigs
+ * @param servicesMap
+ * @param stackProperties
+ * @return
+ */
+ public Map<PropertyInfo, String> getPropertiesWithPropertyType(PropertyType propertyType, Cluster cluster,
+ Map<String, DesiredConfig> desiredConfigs, Map<String, ServiceInfo> servicesMap,
+ Set<PropertyInfo> stackProperties) throws AmbariException {
+ Map<String, Config> actualConfigs = new HashMap<>();
+ Map<PropertyInfo, String> result = new HashMap<>();
+
+ for (Map.Entry<String, DesiredConfig> desiredConfigEntry : desiredConfigs.entrySet()) {
+ String configType = desiredConfigEntry.getKey();
+ DesiredConfig desiredConfig = desiredConfigEntry.getValue();
+ actualConfigs.put(configType, cluster.getConfig(configType, desiredConfig.getTag()));
+ }
+
+ for (Service service : cluster.getServices().values()) {
+ Set<PropertyInfo> serviceProperties = new HashSet<PropertyInfo>(servicesMap.get(service.getName()).getProperties());
+ for (PropertyInfo serviceProperty : serviceProperties) {
+ if (serviceProperty.getPropertyTypes().contains(propertyType)) {
+ String stackPropertyConfigType = fileNameToConfigType(serviceProperty.getFilename());
+ try {
+ String property = actualConfigs.get(stackPropertyConfigType).getProperties().get(serviceProperty.getName());
+ if (null == property){
+ LOG.error(String.format("Unable to obtain property values for %s with property attribute %s. "
+ + "The property does not exist in version %s of %s configuration.",
+ serviceProperty.getName(),
+ propertyType,
+ desiredConfigs.get(stackPropertyConfigType),
+ stackPropertyConfigType
+ ));
+ } else {
+ result.put(serviceProperty, property);
+ }
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ }
+
+
+ for (PropertyInfo stackProperty : stackProperties) {
+ if (stackProperty.getPropertyTypes().contains(propertyType)) {
+ String stackPropertyConfigType = fileNameToConfigType(stackProperty.getFilename());
+ result.put(stackProperty, actualConfigs.get(stackPropertyConfigType).getProperties().get(stackProperty.getName()));
+ }
+ }
+
+ return result;
+ }
+
+ /***
+ * Fetch all the property values of a given PropertyType. For eg: Fetch all cluster configs that are of type "user"
+ * @param stackId
+ * @param propertyType
+ * @param cluster
+ * @param desiredConfigs
+ * @return
+ * @throws AmbariException
+ */
public Set<String> getPropertyValuesWithPropertyType(StackId stackId, PropertyType propertyType,
Cluster cluster, Map<String,
DesiredConfig> desiredConfigs) throws AmbariException {
@@ -555,6 +705,16 @@ public class ConfigHelper {
return getPropertyValuesWithPropertyType(propertyType, cluster, desiredConfigs, servicesMap, stackProperties);
}
+ /***
+ * Fetch all the property values of a given PropertyType. For eg: Fetch all cluster configs that are of type "user"
+ * @param propertyType
+ * @param cluster
+ * @param desiredConfigs
+ * @param servicesMap
+ * @param stackProperties
+ * @return
+ * @throws AmbariException
+ */
public Set<String> getPropertyValuesWithPropertyType(PropertyType propertyType,
Cluster cluster, Map<String, DesiredConfig> desiredConfigs,
Map<String, ServiceInfo> servicesMap,
@@ -592,6 +752,14 @@ public class ConfigHelper {
return result;
}
+ /***
+ * Fetch all the config values of a given PropertyType. For eg: Fetch all stack configs that are of type "user"
+ * @param cluster
+ * @param configType
+ * @param propertyName
+ * @return
+ * @throws AmbariException
+ */
public String getPropertyValueFromStackDefinitions(Cluster cluster, String configType, String propertyName) throws AmbariException {
StackId stackId = cluster.getCurrentStackVersion();
StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(),
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
index 34c2941..2ad92fd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/PropertyInfo.java
@@ -190,6 +190,10 @@ public class PropertyInfo {
return dependsOnProperties;
}
+ public void setPropertyValueAttributes(ValueAttributesInfo propertyValueAttributes) {
+ this.propertyValueAttributes = propertyValueAttributes;
+ }
+
public Set<PropertyDependencyInfo> getDependedByProperties() {
return dependedByProperties;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 56fcd74..a38af29 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -384,10 +384,15 @@ public String getVersion() {
return properties;
}
+ public void setProperties(List properties) {
+ this.properties = properties;
+ }
+
public List<ComponentInfo> getComponents() {
if (components == null) components = new ArrayList<ComponentInfo>();
return components;
}
+
/**
* Finds ComponentInfo by component name
* @param componentName name of the component
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/state/UserGroupInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UserGroupInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UserGroupInfo.java
new file mode 100644
index 0000000..a8c4322
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UserGroupInfo.java
@@ -0,0 +1,50 @@
+/*
+ * 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.state;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+public class UserGroupInfo {
+
+ private String type;
+ private String name;
+
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
index 30a1533..149505a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
@@ -86,6 +86,10 @@ public class ValueAttributesInfo {
@JsonProperty("property-file-type")
private String propertyFileType;
+ @XmlElementWrapper(name = "user-groups")
+ @XmlElements(@XmlElement(name = "property"))
+ private Collection<UserGroupInfo> userGroupEntries;
+
@XmlElement(name = "keystore")
private boolean keyStore;
@@ -133,6 +137,14 @@ public class ValueAttributesInfo {
this.entries = entries;
}
+ public Collection<UserGroupInfo> getUserGroupEntries() {
+ return userGroupEntries;
+ }
+
+ public void setUserGroupEntries(Collection<UserGroupInfo> userGroupEntries) {
+ this.userGroupEntries = userGroupEntries;
+ }
+
public String getHidden() {
return hidden;
}
@@ -313,6 +325,7 @@ public class ValueAttributesInfo {
if (unit != null ? !unit.equals(that.unit) : that.unit != null) return false;
if (delete != null ? !delete.equals(that.delete) : that.delete != null) return false;
if (incrementStep != null ? !incrementStep.equals(that.incrementStep) : that.incrementStep != null) return false;
+ if (userGroupEntries != null ? !userGroupEntries.equals(that.userGroupEntries) : that.userGroupEntries != null) return false;
return true;
}
@@ -339,6 +352,7 @@ public class ValueAttributesInfo {
result = 31 * result + (showPropertyName != null ? showPropertyName.hashCode() : 0);
result = 31 * result + (uiOnlyProperty != null ? uiOnlyProperty.hashCode() : 0);
result = 31 * result + (copy != null ? copy.hashCode() : 0);
+ result = 31 * result + (userGroupEntries != null ? userGroupEntries.hashCode() : 0);
return result;
}
@@ -364,6 +378,7 @@ public class ValueAttributesInfo {
", propertyFileName='" + propertyFileName + '\'' +
", propertyFileType='" + propertyFileType + '\'' +
", copy='" + copy + '\'' +
+ ", userGroupEntries='" + userGroupEntries + '\'' +
'}';
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/resources/configuration-schema.xsd
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/configuration-schema.xsd b/ambari-server/src/main/resources/configuration-schema.xsd
index 1019dd9..18063cb 100644
--- a/ambari-server/src/main/resources/configuration-schema.xsd
+++ b/ambari-server/src/main/resources/configuration-schema.xsd
@@ -107,9 +107,17 @@
<xs:element name="selection-cardinality" type="xs:string" minOccurs="0"/>
<xs:element name="property-file-name" type="xs:string" minOccurs="0"/>
<xs:element name="property-file-type" type="xs:string" minOccurs="0"/>
+ <xs:element name="user-groups" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="property" type="userGroupInfo" minOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
</xs:all>
</xs:complexType>
+
<xs:complexType name="valueEntryInfo">
<xs:all>
<xs:element name="value" type="xs:string" minOccurs="0"/>
@@ -118,6 +126,15 @@
</xs:all>
</xs:complexType>
+ <xs:complexType name="userGroupInfo">
+ <xs:sequence>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="name" type="xs:string" minOccurs="0"/>
+ <xs:element name="type" type="xs:string" minOccurs="0"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
<xs:complexType name="propertyDependencyInfo">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-ANY/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-ANY/scripts/params.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-ANY/scripts/params.py
index a748b33..d1eeaa5 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-ANY/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-ANY/scripts/params.py
@@ -20,6 +20,7 @@ limitations under the License.
import collections
import re
import os
+import ast
import ambari_simplejson as json # simplejson is much faster comparing to Python 2.6 json module and has the same functions set.
@@ -245,7 +246,13 @@ if has_ranger_admin:
user_to_groups_dict[ranger_user] = [ranger_group]
if has_zeppelin_master:
user_to_groups_dict[zeppelin_user] = [zeppelin_group, user_group]
-
+#Append new user-group mapping to the dict
+try:
+ user_group_map = ast.literal_eval(config['hostLevelParams']['user_group'])
+ for key in user_group_map.iterkeys():
+ user_to_groups_dict[key] = user_group_map[key]
+except ValueError:
+ print('User Group mapping (user_group) is missing in the hostLevelParams')
user_to_gid_dict = collections.defaultdict(lambda:user_group)
user_list = json.loads(config['hostLevelParams']['user_list'])
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 19df802..334ab01 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -130,7 +130,7 @@ public class AmbariMetaInfoTest {
private static final String NON_EXT_VALUE = "XXX";
private static final int REPOS_CNT = 3;
- private static final int PROPERTIES_CNT = 62;
+ private static final int PROPERTIES_CNT = 64;
private static final int OS_CNT = 4;
private static TestAmbariMetaInfo metaInfo = null;
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
index 63a9e9c..84fbba3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
@@ -51,15 +51,21 @@ import org.apache.ambari.server.security.TestAuthenticationFactory;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.UserGroupInfo;
+import org.apache.ambari.server.state.ValueAttributesInfo;
import org.apache.ambari.server.topology.TopologyManager;
import org.apache.ambari.server.utils.StageUtils;
import org.easymock.Capture;
@@ -91,6 +97,9 @@ public class AmbariCustomCommandExecutionHelperTest {
@Mock(type = MockType.NICE)
private HostRoleCommand hostRoleCommand;
+ @Mock(type = MockType.NICE)
+ private ConfigHelper configHelper;
+
private Injector injector;
private Clusters clusters;
private AmbariManagementController ambariManagementController;
@@ -100,7 +109,7 @@ public class AmbariCustomCommandExecutionHelperTest {
@Before
public void setup() throws Exception {
- EasyMock.reset(actionManager, hostRoleCommand);
+ EasyMock.reset(actionManager, hostRoleCommand, configHelper);
InMemoryDefaultTestModule module = new InMemoryDefaultTestModule(){
@Override
@@ -109,6 +118,7 @@ public class AmbariCustomCommandExecutionHelperTest {
OVERRIDDEN_SERVICE_CHECK_TIMEOUT_VALUE);
super.configure();
bind(ActionManager.class).toInstance(actionManager);
+ bind(ConfigHelper.class).toInstance(configHelper);
}
};
@@ -132,6 +142,41 @@ public class AmbariCustomCommandExecutionHelperTest {
EasyMock.expect(actionManager.getNextRequestId()).andReturn(1L).anyTimes();
EasyMock.expect(actionManager.getRequestTasks(1L)).andReturn(Collections.singletonList(hostRoleCommand));
+ StackInfo stackInfo = new StackInfo();
+ stackInfo.setName("HDP");
+ stackInfo.setVersion("2.0.6");
+ StackId stackId = new StackId(stackInfo);
+ Map<String, DesiredConfig> desiredConfigMap = new HashMap<String, DesiredConfig>();
+ Map<PropertyInfo, String> userProperties = new HashMap<>();
+ Map<PropertyInfo, String> groupProperties = new HashMap<>();
+ PropertyInfo userProperty = new PropertyInfo();
+ userProperty.setFilename("zookeeper-env.xml");
+ userProperty.setName("zookeeper-user");
+ userProperty.setValue("zookeeperUser");
+ PropertyInfo groupProperty = new PropertyInfo();
+ groupProperty.setFilename("zookeeper-env.xml");
+ groupProperty.setName("zookeeper-group");
+ groupProperty.setValue("zookeeperGroup");
+ ValueAttributesInfo valueAttributesInfo = new ValueAttributesInfo();
+ valueAttributesInfo.setType("user");
+ Set<UserGroupInfo> userGroupEntries = new HashSet<>();
+ UserGroupInfo userGroupInfo = new UserGroupInfo();
+ userGroupInfo.setType("zookeeper-env");
+ userGroupInfo.setName("zookeeper-group");
+ userGroupEntries.add(userGroupInfo);
+ valueAttributesInfo.setUserGroupEntries(userGroupEntries);
+ userProperty.setPropertyValueAttributes(valueAttributesInfo);
+ userProperties.put(userProperty, "zookeeperUser");
+ groupProperties.put(groupProperty, "zookeeperGroup");
+ Map<String, Set<String>> userGroupsMap = new HashMap<>();
+ userGroupsMap.put("zookeeperUser", new HashSet<String>(Arrays.asList("zookeeperGroup")));
+ Cluster cluster = clusters.getCluster("c1");
+ EasyMock.expect(configHelper.getPropertiesWithPropertyType(
+ stackId, PropertyInfo.PropertyType.USER, cluster, desiredConfigMap)).andReturn(userProperties).anyTimes();
+ EasyMock.expect(configHelper.getPropertiesWithPropertyType(
+ stackId, PropertyInfo.PropertyType.GROUP, cluster, desiredConfigMap)).andReturn(groupProperties).anyTimes();
+ EasyMock.expect(configHelper.createUserGroupsMap(stackId, cluster, desiredConfigMap)).andReturn(userGroupsMap).anyTimes();
+
actionManager.sendActions(EasyMock.capture(requestCapture), EasyMock.anyObject(ExecuteActionRequest.class));
EasyMock.expectLastCall();
@@ -160,7 +205,7 @@ public class AmbariCustomCommandExecutionHelperTest {
}, false);
actionRequest.getResourceFilters().add(new RequestResourceFilter("YARN", "RESOURCEMANAGER", Collections.singletonList("c1-c6401")));
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
@@ -176,6 +221,9 @@ public class AmbariCustomCommandExecutionHelperTest {
Assert.assertEquals(1, commands.size());
ExecutionCommand command = commands.get(0).getExecutionCommand();
+ Assert.assertNotNull(command.getHostLevelParams());
+ Assert.assertTrue(command.getHostLevelParams().containsKey(ExecutionCommand.KeyNames.USER_GROUP));
+ Assert.assertEquals("{\"zookeeperUser\":[\"zookeeperGroup\"]}", command.getHostLevelParams().get(ExecutionCommand.KeyNames.USER_GROUP));
Assert.assertEquals(true, command.getForceRefreshConfigTagsBeforeExecution());
}
@@ -205,7 +253,7 @@ public class AmbariCustomCommandExecutionHelperTest {
},
false);
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
@@ -243,7 +291,7 @@ public class AmbariCustomCommandExecutionHelperTest {
}
}, false);
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
@@ -283,7 +331,7 @@ public class AmbariCustomCommandExecutionHelperTest {
}
}, false);
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
@@ -332,7 +380,7 @@ public class AmbariCustomCommandExecutionHelperTest {
}
}, false);
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
Assert.fail(
"Expected an exception since there are no hosts which can run the ZK service check");
@@ -375,7 +423,7 @@ public class AmbariCustomCommandExecutionHelperTest {
}
}, false);
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
Assert.fail("Expected an exception since there are no hosts which can run the ZK service check");
}
@@ -424,7 +472,7 @@ public class AmbariCustomCommandExecutionHelperTest {
HashSet<String> localComponents = new HashSet<>();
EasyMock.expect(execCmd.getLocalComponents()).andReturn(localComponents).anyTimes();
- EasyMock.replay(stage, execCmdWrapper, execCmd);
+ EasyMock.replay(configHelper,stage, execCmdWrapper, execCmd);
ambariCustomCommandExecutionHelper.addExecutionCommandsToStage(actionExecutionContext, stage, new HashMap<String, String>());
Map<String, String> configMap = timeOutCapture.getValues().get(0);
@@ -506,7 +554,7 @@ public class AmbariCustomCommandExecutionHelperTest {
}
}, false);
actionRequest.getResourceFilters().add(new RequestResourceFilter("YARN", "RESOURCEMANAGER", Collections.singletonList("c1-c6401")));
- EasyMock.replay(hostRoleCommand, actionManager);
+ EasyMock.replay(hostRoleCommand, actionManager, configHelper);
ambariManagementController.createAction(actionRequest, requestProperties);
StackId stackId = clusters.getCluster("c1").getDesiredStackVersion();
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/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 c40ff64..3a53388 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
@@ -1246,11 +1246,18 @@ public class AmbariManagementControllerTest {
Map<String, String> configs = new HashMap<String, String>();
configs.put("a", "b");
- ConfigurationRequest cr1,cr2;
+ Map<String, String> hadoopEnvConfigs = new HashMap<>();
+ hadoopEnvConfigs.put("hdfs_user", "myhdfsuser");
+ hadoopEnvConfigs.put("hdfs_group", "myhdfsgroup");
+
+ ConfigurationRequest cr1,cr2, cr3;
+
cr1 = new ConfigurationRequest(cluster1, "core-site","version1",
configs, null);
cr2 = new ConfigurationRequest(cluster1, "hdfs-site","version1",
configs, null);
+ cr3 = new ConfigurationRequest(cluster1, "hadoop-env","version1",
+ hadoopEnvConfigs, null);
ClusterRequest crReq = new ClusterRequest(cluster.getClusterId(), cluster1, null, null);
crReq.setDesiredConfig(Collections.singletonList(cr1));
@@ -1258,6 +1265,9 @@ public class AmbariManagementControllerTest {
crReq = new ClusterRequest(cluster.getClusterId(), cluster1, null, null);
crReq.setDesiredConfig(Collections.singletonList(cr2));
controller.updateClusters(Collections.singleton(crReq), null);
+ crReq = new ClusterRequest(cluster.getClusterId(), cluster1, null, null);
+ crReq.setDesiredConfig(Collections.singletonList(cr3));
+ controller.updateClusters(Collections.singleton(crReq), null);
@@ -1271,11 +1281,13 @@ public class AmbariManagementControllerTest {
assertEquals(cluster1, ec.getClusterName());
Map<String, Map<String, String>> configurations = ec.getConfigurations();
assertNotNull(configurations);
- assertEquals(2, configurations.size());
+ assertEquals(3, configurations.size());
assertTrue(configurations.containsKey("hdfs-site"));
assertTrue(configurations.containsKey("core-site"));
+ assertTrue(configurations.containsKey("hadoop-env"));
assertTrue(ec.getConfigurationAttributes().containsKey("hdfs-site"));
assertTrue(ec.getConfigurationAttributes().containsKey("core-site"));
+ assertTrue(ec.getConfigurationAttributes().containsKey("hadoop-env"));
assertTrue(ec.getCommandParams().containsKey("max_duration_for_retries"));
assertEquals("0", ec.getCommandParams().get("max_duration_for_retries"));
assertTrue(ec.getCommandParams().containsKey("command_retry_enabled"));
@@ -1291,6 +1303,13 @@ public class AmbariManagementControllerTest {
assertNotNull(ec.getCommandParams());
assertTrue(ec.getCommandParams().containsKey("custom_folder"));
assertEquals("dashboards", ec.getCommandParams().get("custom_folder"));
+ assertNotNull(ec.getHostLevelParams());
+ assertTrue(ec.getHostLevelParams().containsKey(ExecutionCommand.KeyNames.USER_LIST));
+ assertEquals("[\"myhdfsuser\"]", ec.getHostLevelParams().get(ExecutionCommand.KeyNames.USER_LIST));
+ assertTrue(ec.getHostLevelParams().containsKey(ExecutionCommand.KeyNames.GROUP_LIST));
+ assertEquals("[\"myhdfsgroup\"]", ec.getHostLevelParams().get(ExecutionCommand.KeyNames.GROUP_LIST));
+ assertTrue(ec.getHostLevelParams().containsKey(ExecutionCommand.KeyNames.USER_GROUP));
+ assertEquals("{\"myhdfsuser\":[\"myhdfsgroup\"]}", ec.getHostLevelParams().get(ExecutionCommand.KeyNames.USER_GROUP));
}
@Test
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
index 8fad94e..84678e6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
@@ -26,6 +26,7 @@ import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import java.io.ByteArrayInputStream;
@@ -72,7 +73,10 @@ import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.ServiceOsSpecific;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.UserGroupInfo;
+import org.apache.ambari.server.state.ValueAttributesInfo;
import org.apache.ambari.server.utils.StageUtils;
+import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -189,7 +193,9 @@ public class ClientConfigResourceProviderTest {
Configuration configuration = PowerMock.createStrictMockAndExpectNew(Configuration.class);
Map<String, String> configMap = createNiceMock(Map.class);
- File mockFile = PowerMock.createNiceMock(File.class);
+ File newFile = File.createTempFile("config",".json",new File("/tmp/"));
+ newFile.deleteOnExit();
+
Runtime runtime = createMock(Runtime.class);
Process process = createNiceMock(Process.class);
@@ -320,14 +326,42 @@ public class ClientConfigResourceProviderTest {
expect(serviceInfo.getOsSpecifics()).andReturn(new HashMap<String, ServiceOsSpecific>()).anyTimes();
Set<String> userSet = new HashSet<String>();
userSet.add("hdfs");
- expect(configHelper.getPropertyValuesWithPropertyType(stackId, PropertyInfo.PropertyType.USER, cluster, desiredConfigMap)).andReturn(userSet);
- PowerMock.expectNew(File.class, new Class<?>[]{String.class}, anyObject(String.class)).andReturn(mockFile).anyTimes();
- PowerMock.createNiceMockAndExpectNew(PrintWriter.class, anyObject());
- expect(mockFile.getParent()).andReturn("");
- PowerMock.mockStatic(Runtime.class);
- expect(mockFile.exists()).andReturn(true);
- String commandLine = "ambari-python-wrap /tmp/stacks/S1/V1/PIG/package/null generate_configs null " +
- "/tmp/stacks/S1/V1/PIG/package /var/lib/ambari-server/tmp/structured-out.json " +
+ expect(configHelper.getPropertyValuesWithPropertyType(
+ stackId, PropertyInfo.PropertyType.USER, cluster, desiredConfigMap)).andReturn(userSet);
+ Map<PropertyInfo, String> userProperties = new HashMap<>();
+ Map<PropertyInfo, String> groupProperties = new HashMap<>();
+ PropertyInfo userProperty = new PropertyInfo();
+ userProperty.setFilename("hadoop-env.xml");
+ userProperty.setName("hdfs-user");
+ userProperty.setValue("hdfsUser");
+
+
+ PropertyInfo groupProperty = new PropertyInfo();
+ groupProperty.setFilename("hadoop-env.xml");
+ groupProperty.setName("hdfs-group");
+ groupProperty.setValue("hdfsGroup");
+ ValueAttributesInfo valueAttributesInfo = new ValueAttributesInfo();
+ valueAttributesInfo.setType("user");
+ Set<UserGroupInfo> userGroupEntries = new HashSet<>();
+ UserGroupInfo userGroupInfo = new UserGroupInfo();
+ userGroupInfo.setType("hadoop-env");
+ userGroupInfo.setName("hdfs-group");
+ userGroupEntries.add(userGroupInfo);
+ valueAttributesInfo.setUserGroupEntries(userGroupEntries);
+ userProperty.setPropertyValueAttributes(valueAttributesInfo);
+ userProperties.put(userProperty, "hdfsUser");
+ groupProperties.put(groupProperty, "hdfsGroup");
+ Map<String, Set<String>> userGroupsMap = new HashMap<>();
+ userGroupsMap.put("hdfsUser", new HashSet<String>(Arrays.asList("hdfsGroup")));
+ expect(configHelper.getPropertiesWithPropertyType(
+ stackId, PropertyInfo.PropertyType.USER, cluster, desiredConfigMap)).andReturn(userProperties).anyTimes();
+ expect(configHelper.getPropertiesWithPropertyType(
+ stackId, PropertyInfo.PropertyType.GROUP, cluster, desiredConfigMap)).andReturn(groupProperties).anyTimes();
+ expect(configHelper.createUserGroupsMap(stackId, cluster, desiredConfigMap)).andReturn(userGroupsMap).anyTimes();
+
+ PowerMock.expectNew(File.class, new Class<?>[]{String.class}, anyObject(String.class)).andReturn(newFile).anyTimes();
+ String commandLine = "ambari-python-wrap /tmp/stacks/S1/V1/PIG/package/null generate_configs "+newFile +
+ " /tmp/stacks/S1/V1/PIG/package /var/lib/ambari-server/tmp/structured-out.json " +
"INFO /var/lib/ambari-server/tmp";
if (System.getProperty("os.name").contains("Windows")) {
@@ -364,6 +398,8 @@ public class ClientConfigResourceProviderTest {
Set<Resource> resources = provider.getResources(request, predicate);
assertFalse(resources.isEmpty());
+ String str = FileUtils.readFileToString(newFile);
+ assertTrue(str.contains("\"user_groups\":\"{\\\"hdfsUser\\\":[\\\"hdfsGroup\\\"]}"));
// verify
verify(managementController, clusters, cluster, ambariMetaInfo, stackId, componentInfo,commandScriptDefinition,
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
index 87a1fc7..0234d79 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
@@ -194,7 +194,7 @@ public class StackManagerTest {
List<ComponentInfo> components = hdfsService.getComponents();
assertEquals(6, components.size());
List<PropertyInfo> properties = hdfsService.getProperties();
- assertEquals(62, properties.size());
+ assertEquals(64, properties.size());
// test a couple of the properties for filename
boolean hdfsPropFound = false;
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/test/python/stacks/2.0.6/configs/default.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/configs/default.json b/ambari-server/src/test/python/stacks/2.0.6/configs/default.json
index 2a27eca..fa7419f 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/configs/default.json
+++ b/ambari-server/src/test/python/stacks/2.0.6/configs/default.json
@@ -20,6 +20,7 @@
"java_home": "/usr/jdk64/jdk1.7.0_45",
"java_version": "8",
"db_name": "ambari",
+ "user_group": "{\"sample\":[\"sample\",\"users\"]}",
"group_list": "[\"hadoop\",\"nobody\",\"users\"]",
"user_list": "[\"hive\",\"oozie\",\"nobody\",\"ambari-qa\",\"flume\",\"hdfs\",\"storm\",\"mapred\",\"hbase\",\"tez\",\"zookeeper\",\"falcon\",\"sqoop\",\"yarn\",\"hcat\"]",
"custom_mysql_jdbc_name" : "mysql-connector-java.jar",
http://git-wip-us.apache.org/repos/asf/ambari/blob/b856c5f3/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/configuration/hadoop-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/configuration/hadoop-env.xml b/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/configuration/hadoop-env.xml
new file mode 100644
index 0000000..4e5ff1a
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/configuration/hadoop-env.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<configuration supports_adding_forbidden="true">
+ <property>
+ <name>hdfs_user</name>
+ <display-name>HDFS User</display-name>
+ <value>hdfs</value>
+ <property-type>USER</property-type>
+ <description>User to run HDFS as</description>
+ <value-attributes>
+ <type>user</type>
+ <overridable>false</overridable>
+ <user-groups>
+ <property>
+ <type>hadoop-env</type>
+ <name>hdfs_group</name>
+ </property>
+ </user-groups>
+ </value-attributes>
+ <on-ambari-upgrade add="true"/>
+ </property>
+ <property>
+ <name>hdfs_group</name>
+ <display-name>HDFS User Group</display-name>
+ <value>hdfs_group</value>
+ <property-type>GROUP</property-type>
+ <description>HDFS user group.</description>
+ <value-attributes>
+ <type>user</type>
+ <overridable>false</overridable>
+ </value-attributes>
+ <on-ambari-upgrade add="true"/>
+ </property>
+</configuration>
\ No newline at end of file