ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alexantone...@apache.org
Subject ambari git commit: AMBARI-17041. Support password type for custom properties (alexantonenko)
Date Fri, 11 Nov 2016 17:48:26 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.5 329dcd09b -> 3b4a7709d


AMBARI-17041. Support password type for custom properties (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3b4a7709
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3b4a7709
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3b4a7709

Branch: refs/heads/branch-2.5
Commit: 3b4a7709dbe6eae3d5c8c0d025bb341dabe952be
Parents: 329dcd0
Author: Alex Antonenko <hiveww@gmail.com>
Authored: Fri Nov 11 19:48:18 2016 +0200
Committer: Alex Antonenko <hiveww@gmail.com>
Committed: Fri Nov 11 19:48:18 2016 +0200

----------------------------------------------------------------------
 .../AmbariManagementControllerImpl.java         | 33 +++++++++++----
 .../controller/ConfigurationResponse.java       |  2 +
 .../ambari/server/utils/SecretReference.java    | 23 +++++++++++
 ambari-web/app/messages.js                      |  1 +
 .../app/mixins/common/configs/configs_saver.js  |  9 +++-
 .../configs/objects/service_config_property.js  |  7 ++++
 .../common/configs/addPropertyWindow.hbs        | 12 ++++++
 ambari-web/app/utils/config.js                  | 27 ++++++++++--
 .../configs/service_configs_by_category_view.js |  5 +++
 .../mixins/common/configs/configs_saver_test.js | 43 ++++++++++++++++++--
 10 files changed, 147 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/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 292021c..5be87b5 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
@@ -819,6 +819,25 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
     Map<String, String> requestProperties = request.getProperties();
 
+    // Configuration attributes are optional. If not present, use default(provided by stack),
otherwise merge default
+    // with request-provided
+    Map<String, Map<String, String>> requestPropertiesAttributes = request.getPropertiesAttributes();
+
+    if (requestPropertiesAttributes != null && requestPropertiesAttributes.containsKey(PASSWORD))
{
+      for (Map.Entry<String, String> requestEntry : requestPropertiesAttributes.get(PASSWORD).entrySet())
{
+        String passwordProperty = requestEntry.getKey();
+        if(requestProperties.containsKey(passwordProperty) && requestEntry.getValue().equals("true"))
{
+          String passwordPropertyValue = requestProperties.get(passwordProperty);
+          if (!SecretReference.isSecret(passwordPropertyValue)) {
+            continue;
+          }
+          SecretReference ref = new SecretReference(passwordPropertyValue, cluster);
+          String refValue = ref.getValue();
+          requestProperties.put(passwordProperty, refValue);
+        }
+      }
+    }
+
     Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes = cluster.getConfigPropertiesTypes(request.getType());
     if(propertiesTypes.containsKey(PropertyType.PASSWORD)) {
       for(String passwordProperty : propertiesTypes.get(PropertyType.PASSWORD)) {
@@ -842,10 +861,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       configs = new HashMap<String, Config>();
     }
 
-    // Configuration attributes are optional. If not present, use default(provided by stack),
otherwise merge default
-    // with request-provided
-    Map<String, Map<String, String>> requestPropertiesAttributes = request.getPropertiesAttributes();
-
     Map<String, Map<String, String>> propertiesAttributes = new HashMap<String,
Map<String,String>>();
 
     StackId currentStackId = cluster.getCurrentStackVersion();
@@ -1540,6 +1555,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     if (request.getDesiredConfig() != null) {
       for (ConfigurationRequest desiredConfig : request.getDesiredConfig()) {
         Map<String, String> requestConfigProperties = desiredConfig.getProperties();
+        Map<String,Map<String,String>> requestConfigAttributes = desiredConfig.getPropertiesAttributes();
 
         // processing password properties
         if(requestConfigProperties != null && !requestConfigProperties.isEmpty())
{
@@ -1549,8 +1565,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
           for (Entry<String, String> property : requestConfigProperties.entrySet())
{
             String propertyName = property.getKey();
             String propertyValue = property.getValue();
-            if (propertiesTypes.containsKey(PropertyType.PASSWORD) &&
-                propertiesTypes.get(PropertyType.PASSWORD).contains(propertyName)) {
+            if ((propertiesTypes.containsKey(PropertyType.PASSWORD) &&
+                propertiesTypes.get(PropertyType.PASSWORD).contains(propertyName)) ||
+                (requestConfigAttributes != null && requestConfigAttributes.containsKey(PASSWORD)
&&
+                requestConfigAttributes.get(PASSWORD).containsKey(propertyName) &&
+                requestConfigAttributes.get(PASSWORD).get(propertyName).equals("true")))
{
               if (SecretReference.isSecret(propertyValue)) {
                 SecretReference ref = new SecretReference(propertyValue, cluster);
                 requestConfigProperties.put(propertyName, ref.getValue());
@@ -1558,7 +1577,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
             }
           }
         }
-        Map<String,Map<String,String>> requestConfigAttributes = desiredConfig.getPropertiesAttributes();
+
         Config clusterConfig = cluster.getDesiredConfigByType(desiredConfig.getType());
         Map<String, String> clusterConfigProperties = null;
         Map<String,Map<String,String>> clusterConfigAttributes = null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
index eef3474..8632c09 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigurationResponse.java
@@ -63,6 +63,7 @@ public class ConfigurationResponse {
     this.version = version;
     this.configs = configs;
     this.configAttributes = configAttributes;
+    SecretReference.replacePasswordsWithReferencesForCustomProperties(configAttributes, configs,
type, version);
   }
 
   public ConfigurationResponse(String clusterName, StackId stackId,
@@ -80,6 +81,7 @@ public class ConfigurationResponse {
     this.configAttributes = configAttributes;
     this.propertiesTypes = propertiesTypes;
     SecretReference.replacePasswordsWithReferences(propertiesTypes, configs, type, version);
+    SecretReference.replacePasswordsWithReferencesForCustomProperties(configAttributes, configs,
type, version);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
b/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
index 84f3109..9788569 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/SecretReference.java
@@ -148,4 +148,27 @@ public class SecretReference {
       }
     }
   }
+
+  /**
+   * Replace real passwords with secret references
+   * @param configAttributes map with config attributes containing properties types as part
of their content
+   * @param propertiesMap map with properties in which replacement will be performed
+   * @param configType configuration type
+   * @param configVersion configuration version
+   */
+  public static void replacePasswordsWithReferencesForCustomProperties(Map<String, Map<String,
String>> configAttributes,
+                                                    Map<String, String> propertiesMap,
+                                                    String configType,
+                                                    Long configVersion){
+    if(configAttributes != null && configAttributes.containsKey("password")) {
+      for(String pwdPropertyName: configAttributes.get("password").keySet()) {
+        if(propertiesMap.containsKey(pwdPropertyName)){
+          if(!propertiesMap.get(pwdPropertyName).equals("")) {
+            String stub = SecretReference.generateStub(configType, configVersion, pwdPropertyName);
+            propertiesMap.put(pwdPropertyName, stub);
+          }
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 5bdea8e..c1ceb03 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -311,6 +311,7 @@ Em.I18n.translations = {
   'common.timezone': 'Timezone',
   'common.loading.eclipses': 'Loading...',
   'common.optional': 'Optional',
+  'common.propertyType': 'Property Type',
   'common.running': 'Running',
   'common.stopped': 'Stopped',
   'common.enter': 'Enter',

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js b/ambari-web/app/mixins/common/configs/configs_saver.js
index 43a77ce..88b9e11 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -454,7 +454,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
     if (!ignoreVersionNote) {
       desired_config.service_config_version_note = serviceConfigNote || "";
     }
-    var attributes = { final: {} };
+    var attributes = { final: {}, password: {}, user: {}, group: {}, text: {}, additional_user_property:
{}, not_managed_hdfs_path: {}, value_from_property_file: {} };
     if (Em.isArray(properties)) {
       properties.forEach(function(property) {
 
@@ -466,11 +466,16 @@ App.ConfigsSaverMixin = Em.Mixin.create({
           if (Em.get(property, 'isFinal')) {
             attributes.final[Em.get(property, 'name')] = "true";
           }
+          if (Em.get(property,'propertyType')) {
+            Em.get(property,'propertyType').map(function(propType) {
+              attributes[propType.toLowerCase()][Em.get(property,'name')] = "true";
+            });
+          }
         }
       }, this);
     }
 
-    if (Object.keys(attributes.final).length) {
+    if (Object.keys(attributes.final).length || Object.keys(attributes.password).length)
{
       desired_config.properties_attributes = attributes;
     }
     return desired_config;

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/app/models/configs/objects/service_config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/objects/service_config_property.js b/ambari-web/app/models/configs/objects/service_config_property.js
index e7a2f52..5d85ae0 100644
--- a/ambari-web/app/models/configs/objects/service_config_property.js
+++ b/ambari-web/app/models/configs/objects/service_config_property.js
@@ -95,6 +95,13 @@ App.ServiceConfigProperty = Em.Object.extend({
   rightSideLabel: false,
 
   /**
+   * type of property
+   * @type {String[]}
+   * @default empty array
+   */
+  propertyType: [],
+
+  /**
    * Text to be shown as placeholder
    * By default savedValue is shown as placeholder
    * @type {String}

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/app/templates/common/configs/addPropertyWindow.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/addPropertyWindow.hbs b/ambari-web/app/templates/common/configs/addPropertyWindow.hbs
index 659435c..1d41b04 100644
--- a/ambari-web/app/templates/common/configs/addPropertyWindow.hbs
+++ b/ambari-web/app/templates/common/configs/addPropertyWindow.hbs
@@ -87,5 +87,17 @@
         {{view Ember.TextArea valueBinding="view.serviceConfigObj.value" rows="4" classNames="input-block-level"}}
       </div>
     </div>
+    <div class="each-row control-group">
+      <label class="control-label">{{t common.propertyType}}</label>
+
+      <div class="controls">
+        {{view Em.Select
+            classNames="input-block-level"
+            multiple="multiple"
+            contentBinding="view.serviceConfigObj.content"
+            selectionBinding="view.serviceConfigObj.propertyType"
+        }}
+      </div>
+    </div>
   {{/if}}
 </form>

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 49f607e..e9c9e24 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -22,6 +22,7 @@ var stringUtils = require('utils/string_utils');
 var validator = require('utils/validator');
 
 var configTagFromFileNameMap = {};
+var PASSWORD = "PASSWORD";
 
 App.config = Em.Object.create({
 
@@ -237,14 +238,34 @@ App.config = Em.Object.create({
     var configs = [],
       filename = App.config.getOriginalFileName(configJSON.type),
       properties = configJSON.properties,
-      finalAttributes = Em.get(configJSON, 'properties_attributes.final') || {};
+      attributes = [];
+      ['FINAL', 'PASSWORD', 'USER', 'GROUP', 'TEXT', 'ADDITIONAL_USER_PROPERTY', 'NOT_MANAGED_HDFS_PATH',
'VALUE_FROM_PROPERTY_FILE'].forEach(function (attribute){
+        var json = {};
+        json[attribute] = Em.get(configJSON, 'properties_attributes.' + attribute.toLowerCase())
|| {};
+        attributes.push(json);
+      });
 
     for (var index in properties) {
       var serviceConfigObj = this.getDefaultConfig(index, filename);
 
       if (serviceConfigObj.isRequiredByAgent !== false) {
         serviceConfigObj.value = serviceConfigObj.savedValue = this.formatPropertyValue(serviceConfigObj,
properties[index]);
-        serviceConfigObj.isFinal = serviceConfigObj.savedIsFinal = finalAttributes[index]
=== "true";
+        serviceConfigObj.isFinal = serviceConfigObj.savedIsFinal = attributes[0]['FINAL'][index]
=== "true";
+
+        var propertyType = [];
+        // iterate through all the attributes, except for FINAL
+        for (var i=1; i<attributes.length; i++) {
+          for (var type in attributes[i]) {
+            if (attributes[i][type][index] === "true") {
+              propertyType.push(type);
+
+              if (type === PASSWORD) {
+                serviceConfigObj.displayType = "password";
+              }
+            }
+          }
+        }
+        serviceConfigObj.propertyType = propertyType;
         serviceConfigObj.isEditable = serviceConfigObj.isReconfigurable;
       }
 
@@ -305,7 +326,7 @@ App.config = Em.Object.create({
       supportsAddingForbidden: this.shouldSupportAddingForbidden(serviceName, fileName),
       serviceName: serviceName,
       displayName: name,
-      displayType: this.getDefaultDisplayType(coreObject ? coreObject.value : ''),
+      displayType: (coreObject && coreObject.propertyType && coreObject.propertyType.contains(PASSWORD))
? 'password' : this.getDefaultDisplayType(coreObject ? coreObject.value : ''),
       description: '',
       category: this.getDefaultCategory(definedInStack, fileName),
       isSecureConfig: this.getIsSecure(name),

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/app/views/common/configs/service_configs_by_category_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/service_configs_by_category_view.js b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
index a95b441..d916adf 100644
--- a/ambari-web/app/views/common/configs/service_configs_by_category_view.js
+++ b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
@@ -412,6 +412,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
     if (selectedConfigGroup.get('isDefault')) {
       config = App.config.createDefaultConfig(propertyObj.name, propertyObj.filename, false,
{
         value: propertyObj.value,
+        propertyType: propertyObj.propertyType,
         category: propertyObj.categoryName,
         isNotSaved: true
       });
@@ -420,6 +421,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
         propertyName: propertyObj.name,
         filename: propertyObj.filename,
         value: propertyObj.value,
+        propertyType: propertyObj.propertyType,
         category: propertyObj.categoryName,
         isNotSaved: true
       }, selectedConfigGroup);
@@ -477,6 +479,8 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
 
       name: '',
       value: '',
+      propertyType: [],
+      content: ['PASSWORD', 'USER', 'GROUP', 'TEXT', 'ADDITIONAL_USER_PROPERTY', 'NOT_MANAGED_HDFS_PATH',
'VALUE_FROM_PROPERTY_FILE'],
       isKeyError: false,
       showFilterLink: false,
       errorMessage: '',
@@ -555,6 +559,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
           if (!serviceConfigObj.isKeyError) {
             propertyObj.name = serviceConfigObj.get('name');
             propertyObj.value = serviceConfigObj.get('value');
+            propertyObj.propertyType = serviceConfigObj.get('propertyType');
             self.createProperty(propertyObj);
             this.hide();
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/3b4a7709/ambari-web/test/mixins/common/configs/configs_saver_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/configs_saver_test.js b/ambari-web/test/mixins/common/configs/configs_saver_test.js
index 4baf303..74e630b 100644
--- a/ambari-web/test/mixins/common/configs/configs_saver_test.js
+++ b/ambari-web/test/mixins/common/configs/configs_saver_test.js
@@ -150,17 +150,54 @@ describe('App.ConfigsSaverMixin', function() {
       })
     });
 
-    it('generates config with final', function() {
-      expect(instanceObject.createDesiredConfig('type1', 'version1', [Em.Object.create({name:
'p1', value: 'v1', isFinal: true, isRequiredByAgent: true}), Em.Object.create({name: 'p2',
value: 'v2', isRequiredByAgent: true})], "note")).to.eql({
+    it('generates config with final, password, user, group, text, additional_user_property,
not_managed_hdfs_path, value_from_property_file', function() {
+      expect(instanceObject.createDesiredConfig('type1', 'version1', [
+          Em.Object.create({name: 'p1', value: 'v1', isFinal: true, isRequiredByAgent: true}),
+          Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent: true}),
+          Em.Object.create({name: 'p3', value: 'v3', isRequiredByAgent: true, propertyType:
["PASSWORD", "USER", "GROUP"]}),
+          Em.Object.create({name: 'p4', value: 'v4', isRequiredByAgent: true, propertyType:
["PASSWORD", "TEXT", "ADDITIONAL_USER_PROPERTY"]}),
+          Em.Object.create({name: 'p5', value: 'v5', isRequiredByAgent: true, propertyType:
["NOT_MANAGED_HDFS_PATH"]}),
+          Em.Object.create({name: 'p6', value: 'v6', isRequiredByAgent: true, propertyType:
["TEXT", "VALUE_FROM_PROPERTY_FILE"]}),
+          Em.Object.create({name: 'p7', value: 'v7', isRequiredByAgent: true, propertyType:
["PASSWORD"]})
+        ], "note")).to.eql({
         "type": 'type1',
         "tag": 'version1',
         "properties": {
           p1: 'v1',
-          p2: 'v2'
+          p2: 'v2',
+          p3: 'v3',
+          p4: 'v4',
+          p5: 'v5',
+          p6: 'v6',
+          p7: 'v7'
         },
         "properties_attributes": {
           final: {
             'p1': "true"
+          },
+          password: {
+            "p3": "true",
+            "p4": "true",
+            "p7": "true"
+          },
+          user: {
+            "p3": "true"
+          },
+          group: {
+            "p3": "true"
+          },
+          text: {
+            "p4": "true",
+            "p6": "true"
+          },
+          additional_user_property: {
+            "p4": "true"
+          },
+          not_managed_hdfs_path: {
+            "p5": "true"
+          },
+          value_from_property_file: {
+            "p6": "true"
           }
         },
         "service_config_version_note": 'note'


Mime
View raw message