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 <[email protected]> Authored: Fri Feb 24 08:42:18 2017 -0800 Committer: Sumit Mohanty <[email protected]> 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
