瀏覽代碼

AMBARI-8451. user and group properties should be created dynamically

Jaimin Jetly 10 年之前
父節點
當前提交
133381bac4

+ 0 - 36
ambari-server/src/main/resources/stacks/HDP/2.2/services/KERBEROS/configuration/kadm5-acl.xml

@@ -1,36 +0,0 @@
-<?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>
-  <property>
-    <name>conf_dir</name>
-    <description>The kadm.acl configuration directory</description>
-    <value>/var/kerberos/krb5kdc</value>
-  </property>
-  <property>
-    <name>content</name>
-    <description>The jinja template for the kadm5.acl file</description>
-    <value>
-      */admin@{{realm}}	*
-
-      {# Append additional realm declarations below #}
-    </value>
-  </property>
-</configuration>

+ 0 - 57
ambari-server/src/main/resources/stacks/HDP/2.2/services/KERBEROS/configuration/kdc-conf.xml

@@ -1,57 +0,0 @@
-<?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>
-  <property>
-    <name>kdcdefaults_kdc_ports</name>
-    <value>88</value>
-  </property>
-  <property>
-    <name>kdcdefaults_kdc_tcp_ports</name>
-    <value>88</value>
-  </property>
-
-  <property>
-    <name>conf_dir</name>
-    <description>The kdc.conf configuration directory</description>
-    <value>/var/kerberos/krb5kdc</value>
-  </property>
-  <property>
-    <name>content</name>
-    <description>The jinja template for the kdc.conf file</description>
-    <value>
-      [kdcdefaults]
-        kdc_ports = {{kdcdefaults_kdc_ports}}
-        kdc_tcp_ports = {{kdcdefaults_kdc_tcp_ports}}
-
-      [realms]
-        {{realm}} = {
-          acl_file = {{kadm5_acl_path}}
-          dict_file = /usr/share/dict/words
-          admin_keytab = {{kadm5_acl_dir}}/kadm5.keytab
-          supported_enctypes = {{libdefaults_default_tgs_enctypes}}
-      }
-
-      {# Append additional realm declarations below #}
-    </value>
-  </property>
-</configuration>

+ 25 - 17
ambari-web/app/controllers/main/admin/serviceAccounts_controller.js

@@ -55,26 +55,34 @@ App.MainAdminServiceAccountsController = App.MainServiceInfoConfigsController.ex
       }
     }
     this.setServiceConfigTags(loadedClusterSiteToTagMap);
-    App.router.get('configurationController').getConfigsByTags(this.get('serviceConfigTags')).done(function (configGroups) {
-      var configSet = App.config.mergePreDefinedWithLoaded(configGroups, [], self.get('serviceConfigTags'), serviceName);
-
-      var misc_configs = configSet.configs.filterProperty('serviceName', self.get('selectedService')).filterProperty('category', 'Users and Groups').filterProperty('isVisible', true).rejectProperty('displayType', 'password');
-
-      misc_configs = App.config.miscConfigVisibleProperty(misc_configs, installedServices);
-
-      var sortOrder = self.get('configs').filterProperty('serviceName', self.get('selectedService')).filterProperty('category', 'Users and Groups').filterProperty('isVisible', true).rejectProperty('displayType', 'password').mapProperty('name');
-
-
-      self.setProxyUserGroupLabel(misc_configs);
+    // load server stored configurations
+    App.router.get('configurationController').getConfigsByTags(this.get('serviceConfigTags')).done(function (serverConfigs) {
+      // load configurations list for installed services
+      App.config.loadAdvancedConfigPartial(installedServices, {
+        queryFilter: 'configurations/StackConfigurations/property_type.matches(.*[USER,GROUP].*)'
+      }, function(advancedConfigs) {
+        // load cluster configs
+        App.config.loadClusterConfig(function(clusterConfigs) {
+          self.createConfigObject(serverConfigs, advancedConfigs.concat(clusterConfigs));
+        });
+      });
+    });
+  },
 
-      self.set('users', self.sortByOrder(sortOrder, misc_configs));
+  /**
+   * Generate configuration object that will be rendered
+   *
+   * @param {Object[]} serverConfigs
+   * @param {Object[]} advancedConfigs
+   */
+  createConfigObject: function(serverConfigs, advancedConfigs) {
+    var configSet = App.config.mergePreDefinedWithLoaded(serverConfigs, advancedConfigs, this.get('serviceConfigTags'), this.get('selectedService'));
+    var miscConfigs = configSet.configs.filterProperty('serviceName', this.get('selectedService')).filterProperty('category', 'Users and Groups').filterProperty('isVisible', true).rejectProperty('displayType', 'password');
 
-      self.setContentProperty('hdfsUser', 'hdfs_user', misc_configs);
-      self.setContentProperty('group', 'user_group', misc_configs);
-      self.setContentProperty('smokeuser', 'smokeuser', misc_configs);
+    miscConfigs = App.config.miscConfigVisibleProperty(miscConfigs, App.Service.find().mapProperty('serviceName'));
 
-      self.set('dataIsLoaded', true);
-    });
+    this.set('users', miscConfigs.filterProperty('isVisible'));
+    this.set('dataIsLoaded', true);
   },
   /**
    * set config value to property of "content"

+ 4 - 1
ambari-web/app/controllers/main/service/info/configs.js

@@ -313,7 +313,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
       if (xhr.statusText === 'abort') return;
       advancedConfigs.pushObjects(properties);
       self.set('advancedConfigs', advancedConfigs);
-      self.trackRequest(self.loadServiceConfigVersions());
+      self.trackRequest(App.config.loadClusterConfig(function(clusterProperties) {
+        self.get('advancedConfigs').pushObjects(clusterProperties);
+        self.trackRequest(self.loadServiceConfigVersions());
+      }));
     }));
   },
 

+ 0 - 375
ambari-web/app/data/HDP2/site_properties.js

@@ -4491,22 +4491,6 @@ module.exports =
       "category": "General",
       "belongsToService": []
     },
-    {
-      "id": "puppet var",
-      "name": "proxyuser_group",
-      "displayName": "Proxy group for Hive, Oozie and Falcon",
-      "description": "",
-      "defaultValue": "users",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "filename": "hadoop-env.xml",
-      "serviceName": "MISC",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE", "OOZIE", "FALCON"],
-      "index": 18
-    },
     {
       "id": "puppet var",
       "name": "ganglia_runtime_dir",
@@ -4521,365 +4505,6 @@ module.exports =
       "category": "General",
       "belongsToService": []
     },
-    {
-      "id": "puppet var",
-      "name": "hdfs_user",
-      "displayName": "HDFS User",
-      "description": "User to run HDFS as",
-      "defaultValue": "hdfs",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "hadoop-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HDFS"],
-      "index": 2
-    },
-    {
-      "id": "puppet var",
-      "name": "mapred_user",
-      "displayName": "MapReduce User",
-      "description": "User to run MapReduce as",
-      "defaultValue": "mapred",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "mapred-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["MAPREDUCE2"],
-      "index": 3
-    },
-    {
-      "id": "puppet var",
-      "name": "yarn_user",
-      "displayName": "YARN User",
-      "description": "User to run YARN as",
-      "defaultValue": "yarn",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "yarn-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["YARN"],
-      "index": 4
-    },
-    {
-      "id": "puppet var",
-      "name": "hbase_user",
-      "displayName": "HBase User",
-      "description": "User to run HBase as",
-      "defaultValue": "hbase",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "hbase-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HBASE"],
-      "index": 5
-    },
-    {
-      "id": "puppet var",
-      "name": "hive_user",
-      "displayName": "Hive User",
-      "description": "User to run Hive as",
-      "defaultValue": "hive",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "hive-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE"],
-      "index": 6
-    },
-    {
-      "id": "puppet var",
-      "name": "hcat_user",
-      "displayName": "HCat User",
-      "description": "User to run HCatalog as",
-      "defaultValue": "hcat",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "hive-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE"],
-      "index": 6
-    },
-    {
-      "id": "puppet var",
-      "name": "webhcat_user",
-      "displayName": "WebHCat User",
-      "description": "User to run WebHCat as",
-      "defaultValue": "hcat",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "hive-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE"],
-      "index": 7
-    },
-    {
-      "id": "puppet var",
-      "name": "oozie_user",
-      "displayName": "Oozie User",
-      "description": "User to run Oozie as",
-      "defaultValue": "oozie",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "oozie-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["OOZIE"],
-      "index": 9
-    },
-    {
-      "id": "puppet var",
-      "name": "falcon_user",
-      "displayName": "Falcon User",
-      "description": "User to run Falcon as",
-      "defaultValue": "falcon",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "falcon-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["FALCON"],
-      "index": 11
-    },
-    {
-      "id": "puppet var",
-      "name": "storm_user",
-      "displayName": "Storm User",
-      "description": "User to run Storm as",
-      "defaultValue": "storm",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "storm-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["STORM"],
-      "index": 10
-    },
-    {
-      "id": "puppet var",
-      "name": "zk_user",
-      "displayName": "ZooKeeper User",
-      "description": "User to run ZooKeeper as",
-      "defaultValue": "zookeeper",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "zookeeper-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["ZOOKEEPER"],
-      "index": 12
-    },
-    {
-      "id": "puppet var",
-      "name": "flume_user",
-      "displayName": "Flume User",
-      "description": "User to run Flume as",
-      "defaultValue": "flume",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "flume-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["FLUME"],
-      "index": 12
-    },
-    {
-      "id": "puppet var",
-      "name": "gmetad_user",
-      "displayName": "Ganglia User",
-      "description": "The user used to run Ganglia",
-      "defaultValue": "nobody",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "ganglia-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["GANGLIA"],
-      "index": 13
-    },
-    {
-      "id": "puppet var",
-      "name": "gmond_user",
-      "displayName": "Gmond User",
-      "description": "The user used to run gmond for Ganglia",
-      "defaultValue": "nobody",
-      "isReconfigurable": false,
-      "displayType": "advanced",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "ganglia-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": []
-    },
-    {
-      "id": "puppet var",
-      "name": "nagios_user",
-      "displayName": "Nagios User",
-      "description": "User to run Nagios as",
-      "defaultValue": "nagios",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "nagios-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["NAGIOS"],
-      "index": 15
-    },
-    {
-      "id": "puppet var",
-      "name": "nagios_group",
-      "displayName": "Nagios Group",
-      "description": "Nagios Group",
-      "defaultValue": "nagios",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "nagios-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["NAGIOS"],
-      "index": 14
-    },
-    {
-      "id": "puppet var",
-      "name": "smokeuser",
-      "displayName": "Smoke Test User",
-      "description": "The user used to run service smoke tests",
-      "defaultValue": "ambari-qa",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "cluster-env.xml",
-      "category": "Users and Groups",
-      "index": 16
-    },
-    {
-      "id": "puppet var",
-      "name": "tez_user",
-      "displayName": "Tez User",
-      "description": "User to run Tez as",
-      "defaultValue": "tez",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "tez-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["TEZ"],
-      "index": 16
-    },
-    {
-      "id": "puppet var",
-      "name": "user_group",
-      "displayName": "Hadoop Group",
-      "description": "Group that the users specified above belong to",
-      "defaultValue": "hadoop",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "cluster-env.xml",
-      "category": "Users and Groups",
-      "index": 17
-    },
-    {
-      "id": "puppet var",
-      "name": "sqoop_user",
-      "displayName": "Sqoop User",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "sqoop-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["SQOOP"],
-      "index": 18
-    },
-    {
-      "id": "puppet var",
-      "name": "knox_user",
-      "displayName": "Knox User",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "knox-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["KNOX"],
-      "index": 18
-    },
-    {
-      "id": "puppet var",
-      "name": "knox_group",
-      "displayName": "Knox Group",
-      "description": "Knox Group",
-      "defaultValue": "knox",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "knox-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["KNOX"],
-      "index": 19
-    },
-    {
-      "id": "puppet var",
-      "name": "kafka_user",
-      "displayName": "Kafka User",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": !App.get('isHadoopWindowsStack'),
-      "serviceName": "MISC",
-      "filename": "kafka-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["KAFKA"],
-      "index": 20
-    },
     {
       "id": "puppet var",
       "name": "rrdcached_base_dir",

+ 0 - 250
ambari-web/app/data/site_properties.js

@@ -2353,256 +2353,6 @@ module.exports =
       "category": "Advanced ganglia-env"
     },
   /**********************************************MISC******************************************/
-    {
-      "id": "puppet var",
-      "name": "proxyuser_group",
-      "displayName": "Proxy group for Hive, WebHCat and Oozie",
-      "description": "",
-      "defaultValue": "users",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "filename": "hadoop-env.xml",
-      "serviceName": "MISC",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE", "OOZIE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "ganglia_runtime_dir",
-      "displayName": "Ganglia runtime directory",
-      "description": "",
-      "defaultValue": "/var/run/ganglia/hdp",
-      "isReconfigurable": false,
-      "displayType": "directory",
-      "isVisible": false,
-      "serviceName": "MISC",
-      "filename": "ganglia-env.xml",
-      "category": "General",
-      "belongsToService": []
-    },
-    {
-      "id": "puppet var",
-      "name": "hdfs_user",
-      "displayName": "HDFS User",
-      "description": "User to run HDFS as",
-      "defaultValue": "hdfs",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "hadoop-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HDFS"]
-    },
-    {
-      "id": "puppet var",
-      "name": "sqoop_user",
-      "displayName": "Sqoop User",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "sqoop-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["SQOOP"]
-    },
-    {
-      "id": "puppet var",
-      "name": "mapred_user",
-      "displayName": "MapReduce User",
-      "description": "User to run MapReduce as",
-      "defaultValue": "mapred",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "mapred-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["MAPREDUCE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "hbase_user",
-      "displayName": "HBase User",
-      "description": "User to run HBase as",
-      "defaultValue": "hbase",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "hbase-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HBASE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "hive_user",
-      "displayName": "Hive User",
-      "description": "User to run Hive as",
-      "defaultValue": "hive",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "hive-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "hcat_user",
-      "displayName": "HCat User",
-      "description": "User to run HCatalog as",
-      "defaultValue": "hcat",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "hive-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "webhcat_user",
-      "displayName": "WebHCat User",
-      "description": "User to run WebHCat as",
-      "defaultValue": "hcat",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "hive-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["HIVE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "oozie_user",
-      "displayName": "Oozie User",
-      "description": "User to run Oozie as",
-      "defaultValue": "oozie",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "oozie-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["OOZIE"]
-    },
-    {
-      "id": "puppet var",
-      "name": "zk_user",
-      "displayName": "ZooKeeper User",
-      "description": "User to run ZooKeeper as",
-      "defaultValue": "zookeeper",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "zookeeper-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["ZOOKEEPER"]
-    },
-    {
-      "id": "puppet var",
-      "name": "gmetad_user",
-      "displayName": "Ganglia User",
-      "description": "The user used to run Ganglia",
-      "defaultValue": "nobody",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "ganglia-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["GANGLIA"]
-    },
-    {
-      "id": "puppet var",
-      "name": "gmond_user",
-      "displayName": "Gmond User",
-      "description": "The user used to run gmond for Ganglia",
-      "defaultValue": "nobody",
-      "isReconfigurable": false,
-      "displayType": "advanced",
-      "isOverridable": false,
-      "isVisible": false,
-      "serviceName": "MISC",
-      "filename": "ganglia-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": []
-    },
-    {
-      "id": "puppet var",
-      "name": "nagios_user",
-      "displayName": "Nagios User",
-      "description": "User to run Nagios as",
-      "defaultValue": "nagios",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "nagios-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["NAGIOS"]
-    },
-    {
-      "id": "puppet var",
-      "name": "nagios_group",
-      "displayName": "Nagios Group",
-      "description": "Nagios Group",
-      "defaultValue": "nagios",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "nagios-env.xml",
-      "category": "Users and Groups",
-      "belongsToService": ["NAGIOS"]
-    },
-    {
-      "id": "puppet var",
-      "name": "smokeuser",
-      "displayName": "Smoke Test User",
-      "description": "The user used to run service smoke tests",
-      "defaultValue": "ambari-qa",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "serviceName": "MISC",
-      "filename": "cluster-env.xml",
-      "category": "Users and Groups",
-      "index": 16
-    },
-    {
-      "id": "puppet var",
-      "name": "user_group",
-      "displayName": "Hadoop Group",
-      "description": "Group that the users specified above belong to",
-      "defaultValue": "hadoop",
-      "isReconfigurable": false,
-      "displayType": "user",
-      "isOverridable": false,
-      "isVisible": true,
-      "serviceName": "MISC",
-      "filename": "cluster-env.xml",
-      "category": "Users and Groups"
-    },
     {
       "id": "puppet var",
       "name": "rrdcached_base_dir",

+ 4 - 0
ambari-web/app/utils/ajax/ajax.js

@@ -570,6 +570,10 @@ var urls = {
     'real': '{stackVersionUrl}/services/{serviceName}/configurations?fields=*',
     'mock': '/data/wizard/stack/hdp/version{stackVersion}/{serviceName}.json'
   },
+  'config.advanced.partial': {
+    'real': '{stackVersionUrl}/services/?StackServices/service_name.in({serviceList})&fields=configurations/*{queryFilter}',
+    'mock': ''
+  },
   'config.config_types': {
     'real': '{stackVersionUrl}/services/{serviceName}?fields=StackServices/config_types',
     'mock': ''

+ 150 - 68
ambari-web/app/utils/config.js

@@ -336,7 +336,7 @@ App.config = Em.Object.create({
         if (!configsPropertyDef) {
           advancedConfigs.filterProperty('name', index).forEach(function (_advancedConfig) {
             var isServiceInstalled = selectedServiceNames.contains(_advancedConfig.serviceName);
-            if (isServiceInstalled) {
+            if (isServiceInstalled || _advancedConfig.serviceName == 'MISC') {
               configsPropertyDef = _advancedConfig;
             }
           }, this);
@@ -370,8 +370,6 @@ App.config = Em.Object.create({
         }
 
         if (!this.getBySitename(serviceConfigObj.get('filename')).someProperty('name', index)) {
-          isAdvanced = advancedConfigs.filterProperty('name', index).someProperty('filename', filename);
-          serviceConfigObj.id = 'site property';
           if (configsPropertyDef) {
             if (configsPropertyDef.isRequiredByAgent === false) {
               continue;
@@ -381,31 +379,14 @@ App.config = Em.Object.create({
             serviceConfigObj.displayType = stringUtils.isSingleLine(serviceConfigObj.value) ? 'advanced' : 'multiLine';
           }
 
+          isAdvanced = advancedConfigs.filterProperty('name', index).someProperty('filename', filename);
+          serviceConfigObj.id = 'site property';
           serviceConfigObj.displayName = configsPropertyDef && configsPropertyDef.displayName ? configsPropertyDef.displayName : index;
           serviceConfigObj.options = configsPropertyDef ? configsPropertyDef.options : null;
+          serviceConfigObj.serviceName = configsPropertyDef && configsPropertyDef.serviceName ? configsPropertyDef.serviceName : serviceName;
+          serviceConfigObj.belongsToService = configsPropertyDef && configsPropertyDef.belongsToService ? configsPropertyDef.belongsToService : [];
           this.calculateConfigProperties(serviceConfigObj, isAdvanced, advancedConfigs);
-
-          if (serviceConfigObj.get('displayType') == 'directories'
-            && (serviceConfigObj.get('category') == 'DataNode'
-              || serviceConfigObj.get('category') == 'NameNode')) {
-            var dirs = serviceConfigObj.get('value').split(',').sort();
-            serviceConfigObj.set('value', dirs.join(','));
-            serviceConfigObj.set('defaultValue', dirs.join(','));
-          }
-
-          if (serviceConfigObj.get('displayType') == 'directory'
-            && serviceConfigObj.get('category') == 'SNameNode') {
-            var dirs = serviceConfigObj.get('value').split(',').sort();
-            serviceConfigObj.set('value', dirs[0]);
-            serviceConfigObj.set('defaultValue', dirs[0]);
-          }
-
-          if (serviceConfigObj.get('displayType') == 'masterHosts') {
-            if (typeof(serviceConfigObj.get('value')) == 'string') {
-              var value = serviceConfigObj.get('value').replace(/\[|]|'|&apos;/g, "").split(',');
-              serviceConfigObj.set('value', value);
-            }
-          }
+          this.setValueByDisplayType(serviceConfigObj);
           configs.push(serviceConfigObj);
         } else {
           mappingConfigs.push(serviceConfigObj);
@@ -418,6 +399,27 @@ App.config = Em.Object.create({
     }
   },
 
+  setValueByDisplayType: function(serviceConfigObj) {
+    if (serviceConfigObj.get('displayType') == 'directories' && (serviceConfigObj.get('category') == 'DataNode' || serviceConfigObj.get('category') == 'NameNode')) {
+      var dirs = serviceConfigObj.get('value').split(',').sort();
+      serviceConfigObj.set('value', dirs.join(','));
+      serviceConfigObj.set('defaultValue', dirs.join(','));
+    }
+
+    if (serviceConfigObj.get('displayType') == 'directory' && serviceConfigObj.get('category') == 'SNameNode') {
+      var dirs = serviceConfigObj.get('value').split(',').sort();
+      serviceConfigObj.set('value', dirs[0]);
+      serviceConfigObj.set('defaultValue', dirs[0]);
+    }
+
+    if (serviceConfigObj.get('displayType') == 'masterHosts') {
+      if (typeof(serviceConfigObj.get('value')) == 'string') {
+        var value = serviceConfigObj.get('value').replace(/\[|]|'|&apos;/g, "").split(',');
+        serviceConfigObj.set('value', value);
+      }
+    }
+  },
+
   /**
    * @param serviceConfigObj : Object
    * @param configsPropertyDef : Object
@@ -604,7 +606,7 @@ App.config = Em.Object.create({
     if (advancedConfigs) {
       advancedConfigs.forEach(function (_config) {
         var configType = this.getConfigTagFromFileName(_config.filename);
-        var configCategory = 'Advanced ' + configType;
+        var configCategory = _config.category || 'Advanced ' + configType;
         var categoryMetaData = null;
         if (_config) {
           if (!(this.get('configMapping').computed().someProperty('name', _config.name) ||
@@ -617,7 +619,7 @@ App.config = Em.Object.create({
             }
             _config.id = "site property";
             _config.category = configCategory;
-            _config.displayName = _config.name;
+            _config.displayName = _config.displayName || _config.name;
             _config.defaultValue = _config.value;
             // make all advanced configs optional and populated by default
             /*
@@ -647,6 +649,10 @@ App.config = Em.Object.create({
   miscConfigVisibleProperty: function (configs, serviceToShow) {
     configs.forEach(function (item) {
       if (item.get('isVisible') && item.belongsToService && item.belongsToService.length) {
+        if (item.get('belongsToService').contains('Cluster') && item.get('displayType') == 'user') {
+          item.set('isVisible', true);
+          return;
+        }
         item.set("isVisible", item.belongsToService.some(function (cur) {
           return serviceToShow.contains(cur)
         }));
@@ -830,19 +836,10 @@ App.config = Em.Object.create({
     var properties = [];
     if (data.items.length) {
       data.items.forEach(function (item) {
-        item = item.StackLevelConfigurations;
-        item.isVisible = true;
-        var serviceName = 'Cluster';
-        properties.push({
-          serviceName: serviceName,
-          name: item.property_name,
-          value: item.property_value,
-          description: item.property_description,
-          isVisible: item.isVisible,
-          isFinal: item.final === "true",
-          defaultIsFinal: item.final === "true",
-          filename: item.filename || item.type
-        });
+        item.StackLevelConfigurations.property_type = item.StackConfigurations.property_type || [];
+        item.StackLevelConfigurations.service_name = 'Cluster';
+        var property = this.createAdvancedPropertyObject(item.StackLevelConfigurations);
+        if (property) properties.push(property);
       }, this);
     }
     params.callback(properties);
@@ -856,8 +853,9 @@ App.config = Em.Object.create({
 
   /**
    * Generate serviceProperties save it to localDB
-   * called form stepController step6WizardController
+   * called from stepController step6WizardController
    *
+   * @method loadAdvancedConfig
    * @param serviceName
    * @param callback
    * @return {object|null}
@@ -877,38 +875,41 @@ App.config = Em.Object.create({
     });
   },
 
+  /**
+   * Load advanced configs by service names etc.
+   * Use this method when you need to get configs for
+   * particular services by single request
+   *
+   * @method loadAdvancedConfigPartial
+   * @param {String[]} serviceNames
+   * @param {Object} opt
+   * @param {Function} callback
+   * @returns {jqXHR}
+   */
+  loadAdvancedConfigPartial: function(serviceNames, opt, callback) {
+    var data = {
+      serviceList: serviceNames.join(','),
+      stackVersionUrl: App.get('stackVersionURL'),
+      stackVersion: App.get('currentStackVersionNumber'),
+      queryFilter: ('&' + opt.queryFilter) || '',
+      callback: callback
+    };
+    return App.ajax.send({
+      name: 'config.advanced.partial',
+      sender: this,
+      data: data,
+      success: 'loadAdvancedConfigPartialSuccess',
+      error: 'loadAdvancedConfigError'
+    });
+  },
+
   loadAdvancedConfigSuccess: function (data, opt, params, request) {
     console.log("TRACE: In success function for the loadAdvancedConfig; url is ", opt.url);
     var properties = [];
     if (data.items.length) {
       data.items.forEach(function (item) {
-        item = item.StackConfigurations;
-        item.isVisible = true;
-        var serviceName = item.service_name;
-        var fileName = item.type;
-        var isHDP2 = App.get('isHadoop2Stack');
-        /**
-         * Properties from mapred-queue-acls.xml are ignored
-         * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
-         * HDP stack version is 1.x
-         */
-        if (fileName !== 'mapred-queue-acls.xml' &&
-          (fileName !== 'capacity-scheduler.xml' || isHDP2)) {
-          var property = {
-            serviceName: serviceName,
-            name: item.property_name,
-            value: item.property_value,
-            description: item.property_description,
-            isVisible: item.isVisible,
-            isFinal: item.final === "true",
-            defaultIsFinal: item.final === "true",
-            filename: item.filename || fileName
-          };
-          if (item.property_type.contains('PASSWORD')) {
-            property.displayType = "password";
-          }
-          properties.push(property);
-        }
+        var property = this.createAdvancedPropertyObject(item.StackConfigurations);
+        if (property) properties.push(property);
       }, this);
     }
     params.callback(properties, request);
@@ -919,6 +920,87 @@ App.config = Em.Object.create({
     params.callback([], request);
   },
 
+  loadAdvancedConfigPartialSuccess: function(data, opt, params, request) {
+    var properties = [];
+    var configurations = data.items.mapProperty('configurations').reduce(function(p,c) { return p.concat(c); });
+    configurations.forEach(function(item) {
+      var property = this.createAdvancedPropertyObject(item.StackConfigurations);
+      if (property) properties.push(property);
+    }, this);
+    params.callback(properties, request);
+  },
+
+  /**
+   * Bootstrap configuration property object according to
+   * format that we using in our application.
+   *
+   * @method createAdvancedPropertyObject
+   * @param {Object} item
+   * @returns {Object|Boolean} 
+   */
+  createAdvancedPropertyObject: function(item) {
+    var serviceName = item.service_name;
+    var fileName = item.type;
+    var isHDP2 = App.get('isHadoop2Stack');
+    /**
+     * Properties from mapred-queue-acls.xml are ignored
+     * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
+     * HDP stack version is 1.x
+     */
+    if (fileName == 'mapred-queue-acls.xml' || (fileName == 'capacity-scheduler.xml' && !isHDP2)) return false;
+    item.isVisible = true;
+    var property = {
+      serviceName: serviceName,
+      name: item.property_name,
+      value: item.property_value,
+      description: item.property_description,
+      isVisible: item.isVisible,
+      isFinal: item.final === "true",
+      defaultIsFinal: item.final === "true",
+      filename: item.filename || fileName
+    };
+
+    return $.extend(property, this.advancedConfigIdentityData(item));
+  },
+  
+  /**
+   * Add aditional properties to advanced property config object.
+   * Additional logic based on `property_type`.
+   *
+   * @method advancedConfigIdentityData
+   * @param {Object} config
+   * @return {Object}
+   */
+  advancedConfigIdentityData: function(config) {
+    var propertyData = {};
+    var proxyUserGroupServices = App.get('isHadoop2Stack') ? ['HIVE', 'OOZIE', 'FALCON'] : ['HIVE', 'OOZIE'];
+
+    if (config.property_type.contains('USER') || config.property_type.contains('GROUP')) {
+      propertyData.id = "puppet var";
+      propertyData.category = 'Users and Groups';
+      propertyData.isVisible = !App.get('isHadoopWindowsStack');
+      propertyData.serviceName = 'MISC';
+      propertyData.isOverridable = false;
+      propertyData.isReconfigurable = false;
+      propertyData.displayName = App.format.normalizeName(config.property_name);
+      propertyData.displayType = 'user';
+      if (config.service_name) {
+        var propertyIndex = config.service_name == 'Cluster' ? 30 : App.StackService.find().mapProperty('serviceName').indexOf(config.service_name);
+        propertyData.belongsToService = [config.service_name];
+        propertyData.index = propertyIndex;
+      } else {
+        propertyData.index = 30;
+      }
+      if (config.property_name == 'proxyuser_group') propertyData.belongsToService = proxyUserGroupServices;
+    }
+
+    if (config.property_type.contains('PASSWORD')) {
+      propertyData.displayType = "password";
+    }
+
+    return propertyData;
+  },
+
   /**
    * Get config types and config type attributes from stack service
    *

+ 1 - 1
ambari-web/app/views/common/configs/services_config.js

@@ -105,7 +105,7 @@ App.ServiceConfigsByCategoryView = Ember.View.extend(App.UserPref, {
   // cacheable )
   categoryConfigs: function () {
     var categoryConfigs = this.get('categoryConfigsAll');
-    return this.orderContentAtLast(categoryConfigs).filterProperty('isVisible', true);
+    return this.orderContentAtLast(this.sortByIndex(categoryConfigs)).filterProperty('isVisible', true);
   }.property('categoryConfigsAll.@each.isVisible').cacheable(),
 
   /**

+ 155 - 9
ambari-web/test/mock_data_setup/configs_mock_data.js

@@ -30,12 +30,10 @@ module.exports = {
       },
       {
         "tag":"version1",
-        "type":"global",
+        "type":"hadoop-env",
         "properties":{
           "hadoop_heapsize":"1024",
-          "storm_log_dir": "/var/log/storm",
-          "stormuiserver_host": "c6401.ambari.apache.org",
-          "nonexistent_property": "some value"
+          "hdfs_user": "hdfs"
         }
       },
       {
@@ -72,6 +70,15 @@ module.exports = {
           "multi_line_property": "value \n value"
         }
       },
+      {
+        "tag": "version1",
+        "type": "storm-env",
+        "properties": {
+          "nonexistent_property": "some value",
+          "storm_log_dir": "/var/log/storm",
+          "stormuiserver_host": "c6401.ambari.apache.org"
+        }
+      },
       {
         "tag":"version1",
         "type":"zoo.cfg",
@@ -86,9 +93,9 @@ module.exports = {
   },
   setupServiceConfigTagsObject: function(serviceName) {
     var configTags = {
-      STORM: ['global','storm-site'],
-      HDFS: ['global','hdfs-site','core-site','hdfs-log4j'],
-      ZOOKEEPER: ['global', 'zoo.cfg']
+      STORM: ['storm-env','storm-site'],
+      HDFS: ['hadoop-env','hdfs-site','core-site','hdfs-log4j'],
+      ZOOKEEPER: ['hadoop-env', 'zoo.cfg']
     };
     var configTagsObject = [];
     if (serviceName) {
@@ -265,7 +272,7 @@ module.exports = {
         "name":"nonexistent_property",
         "value":"some value",
         "defaultValue":"some value",
-        "filename":"global.xml",
+        "filename":"storm-env.xml",
         "isUserProperty":false,
         "isOverridable":true,
         "showLabel":true,
@@ -339,7 +346,7 @@ module.exports = {
         "name":"storm_log_dir",
         "value":"/var/log/storm",
         "defaultValue":"/var/log/storm",
-        "filename":"global.xml",
+        "filename":"storm-env.xml",
         "isUserProperty":false,
         "isOverridable":true,
         "showLabel":true,
@@ -356,5 +363,144 @@ module.exports = {
         "displayName":"storm_log_dir"
       }
     ];
+  },
+
+  advancedConfigs: {
+    items: [
+      {
+        "StackConfigurations" : {
+          "final" : "false",
+          "property_description" : "Proxy user group.",
+          "property_name" : "proxyuser_group",
+          "property_type" : [
+            "GROUP"
+          ],
+          "property_value" : "users",
+          "service_name" : "HDFS",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "hadoop-env.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "final" : "true",
+          "property_description" : "dfs.datanode.data.dir description",
+          "property_name" : "dfs.datanode.data.dir",
+          "property_type" : [ ],
+          "property_value" : "/hadoop/hdfs/data",
+          "service_name" : "HDFS",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "hdfs-site.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "final" : "true",
+          "property_description" : "to enable dfs append",
+          "property_name" : "dfs.support.append",
+          "property_type" : [ ],
+          "property_value" : "true",
+          "service_name" : "HDFS",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "hdfs-site.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "final" : "false",
+          "property_description" : "User to run HDFS as",
+          "property_name" : "hdfs_user",
+          "property_type" : [
+            "USER"
+          ],
+          "property_value" : "hdfs",
+          "service_name" : "HDFS",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "hadoop-env.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "final" : "false",
+          "property_description" : "The permissions that should be there on dfs.datanode.data.dir\n      directories. The datanode will not come up if the permissions are\n      different on existing dfs.datanode.data.dir directories. If the directories\n      don't exist, they will be created with this permission.",
+          "property_name" : "dfs.datanode.data.dir.perm",
+          "property_type" : [ ],
+          "property_value" : "750",
+          "service_name" : "HDFS",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "hdfs-site.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "final" : "false",
+          "property_description" : "\n      DB user password.\n\n      IMPORTANT: if password is emtpy leave a 1 space string, the service trims the value,\n      if empty Configuration assumes it is NULL.\n    ",
+          "property_name" : "oozie.service.JPAService.jdbc.password",
+          "property_type" : [
+            "PASSWORD"
+          ],
+          "property_value" : " ",
+          "service_name" : "OOZIE",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "oozie-site.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "final" : "false",
+          "property_description" : "prop description",
+          "property_name" : "storm_log_dir",
+          "property_type" : [],
+          "property_value" : " ",
+          "service_name" : "STORM",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "storm-env.xml"
+        }
+      }
+
+    ]
+  },
+  
+  advancedClusterConfigs: {
+    items: [
+      {
+        "StackConfigurations" : {
+          "property_type" : [ ]
+        },
+        "StackLevelConfigurations" : {
+          "final" : "false",
+          "property_description" : "Whether to ignore failures on users and group creation",
+          "property_name" : "ignore_groupsusers_create",
+          "property_value" : "false",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "cluster-env.xml"
+        }
+      },
+      {
+        "StackConfigurations" : {
+          "property_type" : [
+            "GROUP"
+          ]
+        },
+        "StackLevelConfigurations" : {
+          "final" : "false",
+          "property_description" : "Hadoop user group.",
+          "property_name" : "user_group",
+          "property_value" : "hadoop",
+          "stack_name" : "HDP",
+          "stack_version" : "2.2",
+          "type" : "cluster-env.xml"
+        }
+      }
+    ]
   }
+  
 }

+ 108 - 0
ambari-web/test/utils/config_test.js

@@ -613,4 +613,112 @@ describe('App.config', function () {
 
   });
 
+  describe('#createAdvancedPropertyObject', function() {
+    var tests = [
+      {
+        name: 'proxyuser_group',
+        cases: [
+          {
+            key: 'displayType',
+            e: 'user'
+          },
+          {
+            key: 'serviceName',
+            e: 'MISC'
+          },
+          {
+            key: 'belongsToService',
+            e: ['HIVE', 'OOZIE']
+          }
+        ]
+      },
+      {
+        name: 'oozie.service.JPAService.jdbc.password',
+        cases: [
+          {
+            key: 'displayType',
+            e: 'password'
+          }
+        ]
+      }
+    ];
+
+    var properties = [];
+    modelSetup.advancedConfigs.items.forEach(function(item) {
+      properties.push(App.config.createAdvancedPropertyObject(item.StackConfigurations));
+    });
+    
+    tests.forEach(function(test) {
+      test.cases.forEach(function(testCase) {
+        it('config property `{0}` `{1}` key should be`{2}`'.format(test.name, testCase.key, testCase.e), function() {
+          var property = properties.findProperty('name', test.name);
+          expect(Em.get(property, testCase.key)).to.eql(testCase.e);
+        });
+      });
+    });
+  });
+
+  describe('#mergePreDefinedWithLoaded', function() {
+    var result;
+
+    before(function() {
+      setups.setupStackVersion(this, 'HDP-2.2');
+      loadServiceModelsData(['HDFS', 'STORM']);
+      App.config.loadAdvancedConfigSuccess(modelSetup.advancedConfigs, { url: '/serviceName/configurations'}, {
+        callback: function(advancedConfigs) {
+          App.config.loadClusterConfigSuccess(modelSetup.advancedClusterConfigs, { url: '/cluster/configurations'}, {
+            callback: function(clusterConfigs) {
+              var configCategories = modelSetup.setupConfigGroupsObject();
+              var tags = [
+                {newTagName: null, tagName: 'version1', siteName: 'hadoop-env'},
+                {newTagName: null, tagName: 'version1', siteName: 'hdfs-site'},
+                {newTagName: null, tagName: 'version1', siteName: 'cluster-env'},
+                {newTagName: null, tagName: 'version1', siteName: 'storm-env'}
+              ];
+              var serviceName = 'STORM';
+              result = App.config.mergePreDefinedWithLoaded(configCategories, advancedConfigs.concat(clusterConfigs), tags, serviceName);
+            }
+          });
+        }
+      });
+    });
+
+    after(function() {
+      setups.restoreStackVersion(this);
+      removeServiceModelData(['HDFS', 'STORM']);
+    });
+    
+    var propertyTests = [
+      {
+        name: 'hdfs_user',
+        cases: [
+          {
+            key: 'displayType',
+            e: 'user'
+          },
+          {
+            key: 'isVisible',
+            e: true
+          },
+          {
+            key: 'serviceName',
+            e: 'MISC'
+          },
+          {
+            key: 'category',
+            e: 'Users and Groups'
+          }
+        ]
+      }
+    ];
+    propertyTests.forEach(function(test) {
+      test.cases.forEach(function(testCase) {
+        it('config property `{0}` `{1}` key should be`{2}`'.format(test.name, testCase.key, testCase.e), function() {
+          var property = result.configs.findProperty('name', test.name);
+          expect(Em.get(property, testCase.key)).to.equal(testCase.e);
+        });
+      });
+    });
+  });
+
 });