You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/05/12 22:49:18 UTC

[1/7] ambari git commit: AMBARI-11081. Kerberos: cannot get passed "Install and Test Kerberos Client" step (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk c94780aa3 -> e6b3972f4


AMBARI-11081. Kerberos: cannot get passed "Install and Test Kerberos Client" step (alexantonenko)


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

Branch: refs/heads/trunk
Commit: e6b3972f4dc28cae594c8c5719c84986e8044e30
Parents: bcfffdb
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 21:29:14 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 .../main/admin/kerberos/step3_controller.js     | 19 +++++-
 ambari-web/app/messages.js                      |  1 +
 .../app/templates/main/admin/kerberos/step3.hbs | 71 +++++++++++++++++++-
 3 files changed, 89 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e6b3972f/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js
index ef1ef8e..8946481 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js
@@ -21,6 +21,7 @@ App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({
   clusterDeployState: 'KERBEROS_DEPLOY',
   serviceName: 'KERBEROS',
   componentName: 'KERBEROS_CLIENT',
+  ignore: undefined,
 
   commands: ['installKerberos', 'testKerberos'],
 
@@ -102,6 +103,22 @@ App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({
     } else {
       wizardController.setLowerStepsDisable(3);
     }
-  }.observes('tasks.@each.status')
+  }.observes('tasks.@each.status'),
+
+  /**
+   * Show or hide warning to ignore errors and continue with the install
+   */
+  showIgnore: function() {
+    return this.get('tasks').someProperty('showRetry', true);
+  }.property('tasks.@each.showRetry'),
+
+  /**
+   * Enable or disable next button if ignore checkbox ticked
+   */
+  ignoreAndProceed: function() {
+    if (this.get('showIgnore')) {
+      this.set('isSubmitDisabled', !this.get('ignore'));
+    }
+  }.observes('ignore','showIgnore')
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6b3972f/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 0f33660..3bc1cab 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -987,6 +987,7 @@ Em.I18n.translations = {
   'admin.kerberos.wizard.step1.header': 'Get Started',
   'admin.kerberos.wizard.step2.header': 'Configure Kerberos',
   'admin.kerberos.wizard.step3.header': 'Install and Test Kerberos Client',
+  'admin.kerberos.wizard.step3.checkbox.ignoreAndProceed.label': 'Ignore errors and continue to next step',
   'admin.kerberos.wizard.step4.header': 'Configure Identities',
   'admin.kerberos.wizard.step5.header': 'Confirm Configuration',
   'admin.kerberos.wizard.step6.header': 'Stop Services',

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6b3972f/ambari-web/app/templates/main/admin/kerberos/step3.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step3.hbs b/ambari-web/app/templates/main/admin/kerberos/step3.hbs
index c74b677..a3a45a6 100644
--- a/ambari-web/app/templates/main/admin/kerberos/step3.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos/step3.hbs
@@ -16,5 +16,74 @@
 * limitations under the License.
 }}
 <div id="kerberos-wizard-step3">
-  {{template "templates/common/progress"}}
+    <div id="common-progress-page">
+        <h2>{{view.headerTitle}}</h2>
+
+        <div {{bindAttr class="view.noticeClass"}}>{{{view.notice}}}
+          {{#if controller.showRetry}}
+              <a href="#" {{action retry target="controller"}}>
+                {{t common.retry}}
+              </a>
+          {{/if}}
+        </div>
+      {{#if controller.isLoaded}}
+          <div class="clearfix">
+            {{#each task in controller.tasks}}
+              {{#view view.taskView contentBinding="task"}}
+                  <div class="item">
+                      <div {{bindAttr class=":pull-left view.linkClass view.parentView.labelWidth"}}>
+                          <i {{bindAttr class="view.icon view.iconColor"}}></i>
+                          <a {{action "showHostProgressPopup" task target="controller"}} >{{task.title}}</a>
+                      </div>
+                      <div {{bindAttr class="view.showProgressBar::hide :row :span5 :pull-left" }}>
+                          <div {{bindAttr class=":progress-bar controller.isRollback::span8 controller.isRollback:span3"}}>
+                              <div class="progress-striped active progress-info progress">
+                                  <div class="bar" {{bindAttr style="view.barWidth"}}></div>
+                              </div>
+                          </div>
+                          <div {{bindAttr class=":span1 view.hidePercent:noDisplay"}}>{{task.progress}}&#37;</div>
+                      </div>
+                      <div>
+                        {{#if task.showRetry}}
+                            <a {{action retryTask target="controller"}} class="btn btn-primary retry"
+                                                                        rel="tooltip"
+                                                                        data-trigger="click" {{bindAttr title="view.showDBTooltip:testDBRetryTooltip"}}>
+                                <i class="icon-repeat icon-white"></i>
+                              {{t common.retry}}
+                            </a>
+
+                        {{/if}}
+                        {{#if task.showRollback}}
+                            <a {{action rollback target="controller"}} class="btn btn-primary retry">
+                                <i class="icon-repeat icon-white"></i>
+                              {{t common.rollBack}}
+                            </a>
+                        {{/if}}
+                        {{#if task.showSkip}}
+                            <a {{action skipTask target="controller"}} class="btn btn-primary retry">
+                                <i class="icon-step-forward icon-white"></i>
+                              {{t common.skip}}
+                            </a>
+                        {{/if}}
+                      </div>
+                  </div>
+              {{/view}}
+
+            {{/each}}
+          </div>
+        {{#if showIgnore}}
+            <div class="alert alert-warning">
+                <label>{{view Em.Checkbox classNames="checkbox" checkedBinding="ignore"}} {{t admin.kerberos.wizard.step3.checkbox.ignoreAndProceed.label}}</label>
+            </div>
+        {{/if}}
+      {{else}}
+          <div class="spinner"></div>
+      {{/if}}
+        <div class="btn-area">
+          {{#if view.showBackButton}}
+              <button class="btn pull-left" {{bindAttr disabled="controller.isBackButtonDisabled"}} {{action back target="controller"}}>&larr; {{t common.back}}</button>
+          {{/if}}
+            <button class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action done target="controller"}}>{{{view.submitButtonText}}}</button>
+        </div>
+    </div>
 </div>


[2/7] ambari git commit: AMBARI-11078. Hide "Regenerate Keytabs" action from the UI if "Manual Kerberos" option is selected (alexantonenko)

Posted by al...@apache.org.
AMBARI-11078. Hide "Regenerate Keytabs" action from the UI if "Manual Kerberos" option is selected (alexantonenko)


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

Branch: refs/heads/trunk
Commit: f085f59e7ce04c991c36af97f5b5590fb0e9bbe3
Parents: bd8a5f9
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 21:20:34 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 .../app/controllers/main/admin/kerberos.js      | 23 ++++++++++++++++++++
 .../app/templates/main/admin/kerberos.hbs       |  4 +++-
 ambari-web/app/utils/ajax/ajax.js               |  9 ++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f085f59e/ambari-web/app/controllers/main/admin/kerberos.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos.js b/ambari-web/app/controllers/main/admin/kerberos.js
index 48691f1..702d585 100644
--- a/ambari-web/app/controllers/main/admin/kerberos.js
+++ b/ambari-web/app/controllers/main/admin/kerberos.js
@@ -25,6 +25,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
   securityEnabled: false,
   dataIsLoaded: false,
   isRecommendedLoaded: true,
+  kdc_type: 'none',
   getAddSecurityWizardStatus: function () {
     return App.db.getSecurityWizardStatus();
   },
@@ -230,6 +231,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
       this.set('dataIsLoaded', true);
     } else {
       //get Security Status From Server
+      this.getSecurityType();
       return this.getSecurityStatus();
     }
   },
@@ -365,6 +367,27 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
     }
   },
 
+  getSecurityType: function () {
+    if (this.get('securityEnabled')) {
+      App.ajax.send({
+        name: 'admin.security.cluster_configs.kerberos',
+        sender: this,
+        data: {
+          clustName: 'c1'
+        },
+        success: 'getSecurityTypeSuccess'
+      })
+    }
+  },
+
+  getSecurityTypeSuccess: function (data, opt, params) {
+    this.set('kdc_type', data.items && Em.get(data.items[0], 'properties.kdc_type') ? Em.get(data.items[0], 'properties.kdc_type') : 'none' );
+  },
+
+  isManualKerberos: function () {
+    return this.get('kdc_type') === 'none';
+  }.property('kdc_type'),
+
   checkState: function(data, opt, params) {
     var res = Em.get(data, 'Services.attributes.kdc_validation_result');
     var message = Em.get(data, 'Services.attributes.kdc_validation_failure_details');

http://git-wip-us.apache.org/repos/asf/ambari/blob/f085f59e/ambari-web/app/templates/main/admin/kerberos.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos.hbs b/ambari-web/app/templates/main/admin/kerberos.hbs
index 23eab55..7b86cb3 100644
--- a/ambari-web/app/templates/main/admin/kerberos.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos.hbs
@@ -20,7 +20,9 @@
     <div>
       <p class="text-success">{{t admin.security.enabled}}
         <a class="btn btn-padding btn-warning admin-disable-security-btn" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.kerberos.button.disable}} </a>
-        <button class="btn btn-success"{{action regenerateKeytabs target="controller"}}><i class="icon-repeat"></i> {{t admin.kerberos.button.regenerateKeytabs}}</button>
+        {{#unless isManualKerberos}}
+          <button class="btn btn-success"{{action regenerateKeytabs target="controller"}}><i class="icon-repeat"></i> {{t admin.kerberos.button.regenerateKeytabs}}</button>
+        {{/unless}}
         <br/>
       </p>
     </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f085f59e/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index cbc0370..8998158 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -1350,6 +1350,15 @@ var urls = {
       };
     }
   },
+  'admin.security.cluster_configs.kerberos': {
+    'real': '/clusters/{clusterName}/configurations?type=kerberos-env&fields=properties/*',
+    'mock': '',
+    'format': function () {
+      return {
+        timeout: 10000
+      };
+    }
+  },
   'admin.get.all_configurations': {
     'real': '/clusters/{clusterName}/configurations?{urlParams}',
     'mock': '',


[4/7] ambari git commit: AMBARI-11072. Files View: Support Auto Create and Cluster Association (alexantonenko)

Posted by al...@apache.org.
AMBARI-11072. Files View: Support Auto Create and Cluster Association (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 7ccaca98597f1c448096d5a1b9ace0d17a3f34c0
Parents: c94780a
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 20:10:56 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 .../view/filebrowser/DownloadService.java       |  1 -
 .../view/filebrowser/FileOperationService.java  |  7 +-
 .../apache/ambari/view/filebrowser/HdfsApi.java |  5 ++
 .../ambari/view/filebrowser/HdfsService.java    | 17 ++++-
 .../view/filebrowser/PropertyValidator.java     | 72 ++++++++++++++++++++
 .../resources/ui/app/components/uploader.js     |  2 +-
 contrib/views/files/src/main/resources/view.xml | 17 ++++-
 .../view/filebrowser/FilebrowserTest.java       |  7 +-
 .../view/filebrowser/HdfsServiceTest.java       | 49 +++++++++++++
 9 files changed, 167 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
index 063d453..1685450 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/DownloadService.java
@@ -53,7 +53,6 @@ import org.apache.hadoop.fs.FileStatus;
 import org.apache.ambari.view.ViewContext;
 import org.apache.hadoop.security.AccessControlException;
 import org.json.simple.JSONObject;
-//import org.glassfish.jersey.server.ChunkedOutput;
 
 /**
  * Service for download and aggregate files

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
index 4628b1d..ded3684 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileOperationService.java
@@ -33,6 +33,7 @@ import javax.xml.bind.annotation.XmlRootElement;
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.filebrowser.utils.NotFoundFormattedException;
 import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException;
+import org.json.simple.JSONObject;
 
 /**
  * File operations service
@@ -57,8 +58,10 @@ public class FileOperationService extends HdfsService {
   @Produces(MediaType.APPLICATION_JSON)
   public Response listdir(@QueryParam("path") String path) {
     try {
-      return Response.ok(
-          getApi(context).fileStatusToJSON(getApi(context).listdir(path))).build();
+      JSONObject response = new JSONObject();
+      response.put("files", getApi(context).fileStatusToJSON(getApi(context).listdir(path)));
+      response.put("meta", getApi(context).fileStatusToJSON(getApi(context).getFileStatus(path)));
+      return Response.ok(response).build();
     } catch (WebApplicationException ex) {
       throw ex;
     } catch (FileNotFoundException ex) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsApi.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsApi.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsApi.java
index ef87001..b521085 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsApi.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsApi.java
@@ -33,6 +33,8 @@ import java.util.Map;
 
 import org.apache.hadoop.security.UserGroupInformation;
 import org.json.simple.JSONArray;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.LinkedHashMap;
 
@@ -40,6 +42,8 @@ import java.util.LinkedHashMap;
  * Hdfs Business Delegate
  */
 public class HdfsApi {
+  protected static final Logger logger = LoggerFactory.getLogger(HdfsApi.class);
+
   private final Configuration conf = new Configuration();
   private final Map<String, String> params;
 
@@ -55,6 +59,7 @@ public class HdfsApi {
    */
   public HdfsApi(final String defaultFs, String username, Map<String, String> params) throws IOException,
       InterruptedException {
+    logger.info("Files View HdfsApi is connecting to '%s'", defaultFs);
     this.params = params;
     conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
     conf.set("fs.webhdfs.impl", "org.apache.hadoop.hdfs.web.WebHdfsFileSystem");

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
index 765cb79..c66bd8f 100644
--- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/HdfsService.java
@@ -21,7 +21,6 @@ package org.apache.ambari.view.filebrowser;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.ambari.view.ViewContext;
-import org.apache.ambari.view.filebrowser.utils.MisconfigurationFormattedException;
 import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.slf4j.Logger;
@@ -70,8 +69,9 @@ public abstract class HdfsService {
     if (_api == null) {
 //      Thread.currentThread().setContextClassLoader(null);
       String defaultFs = context.getProperties().get("webhdfs.url");
-      if (defaultFs == null)
-        throw new MisconfigurationFormattedException("webhdfs.url");
+
+      defaultFs = normalizeFsUrl(defaultFs);
+
       try {
         _api = new HdfsApi(defaultFs, getDoAsUsername(context), getHdfsAuthParams(context));
       } catch (Exception ex) {
@@ -81,6 +81,17 @@ public abstract class HdfsService {
     return _api;
   }
 
+  protected static String normalizeFsUrl(String defaultFs) {
+    //TODO: Don't add port if HA is enabled
+    if (!defaultFs.matches("^[^:]+://.*$"))
+      defaultFs = "webhdfs://" + defaultFs;
+
+    if (!defaultFs.matches("^.*:\\d+$"))
+      defaultFs = defaultFs + ":50070";
+
+    return defaultFs;
+  }
+
   private static Map<String, String> getHdfsAuthParams(ViewContext context) {
     String auth = context.getProperties().get("webhdfs.auth");
     Map<String, String> params = new HashMap<String, String>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/PropertyValidator.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/PropertyValidator.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/PropertyValidator.java
new file mode 100644
index 0000000..abc4f2b
--- /dev/null
+++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/PropertyValidator.java
@@ -0,0 +1,72 @@
+/**
+ * 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.view.filebrowser;
+
+import org.apache.ambari.view.ViewInstanceDefinition;
+import org.apache.ambari.view.validation.ValidationResult;
+import org.apache.ambari.view.validation.Validator;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+public class PropertyValidator implements Validator {
+
+  public static final String WEBHDFS_URL = "webhdfs.url";
+
+  @Override
+  public ValidationResult validateInstance(ViewInstanceDefinition viewInstanceDefinition, ValidationContext validationContext) {
+    return null;
+  }
+
+  @Override
+  public ValidationResult validateProperty(String property, ViewInstanceDefinition viewInstanceDefinition, ValidationContext validationContext) {
+    if (property.equals(WEBHDFS_URL)) {
+      String webhdfsUrl = viewInstanceDefinition.getPropertyMap().get(WEBHDFS_URL);
+      try {
+        new URI(webhdfsUrl);
+      } catch (URISyntaxException e) {
+        return new InvalidPropertyValidationResult(false, "Must be valid URL");
+      }
+    }
+    return ValidationResult.SUCCESS;
+  }
+
+  public static class InvalidPropertyValidationResult implements ValidationResult {
+    private boolean valid;
+    private String detail;
+
+    public InvalidPropertyValidationResult(boolean valid, String detail) {
+      this.valid = valid;
+      this.detail = detail;
+    }
+
+    @Override
+    public boolean isValid() {
+      return valid;
+    }
+
+    @Override
+    public String getDetail() {
+      return detail;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/resources/ui/app/components/uploader.js
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/resources/ui/app/components/uploader.js b/contrib/views/files/src/main/resources/ui/app/components/uploader.js
index 9e413e0..57a1a50 100644
--- a/contrib/views/files/src/main/resources/ui/app/components/uploader.js
+++ b/contrib/views/files/src/main/resources/ui/app/components/uploader.js
@@ -115,4 +115,4 @@ App.FileUploaderComponent = Ember.Component.extend({
     readonly:true,
     classNames:['form-control']
   })
-});
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/main/resources/view.xml b/contrib/views/files/src/main/resources/view.xml
index eaf1a02..2a9eea5 100644
--- a/contrib/views/files/src/main/resources/view.xml
+++ b/contrib/views/files/src/main/resources/view.xml
@@ -21,17 +21,22 @@
 
     <min-ambari-version>1.7.*</min-ambari-version>
 
+    <validator-class>org.apache.ambari.view.filebrowser.PropertyValidator</validator-class>
+
     <parameter>
         <name>webhdfs.url</name>
         <description>Enter the WebHDFS FileSystem URI. Typically this is the dfs.namenode.http-address property in the hdfs-site.xml configuration. URL must be accessible from Ambari Server.</description>
         <label>WebHDFS FileSystem URI</label>
         <placeholder>webhdfs://namenode:50070</placeholder>
+        <default-value>webhdfs://localhost:50070</default-value>
         <required>true</required>
+        <cluster-config>hdfs-site/dfs.namenode.http-address</cluster-config>
     </parameter>
     <parameter>
         <name>webhdfs.username</name>
         <description>doAs for proxy user for HDFS. By default, uses the currently logged-in Ambari user.</description>
         <label>WebHDFS Username</label>
+        <default-value>${username}</default-value>
         <required>false</required>
     </parameter>
     <parameter>
@@ -39,6 +44,7 @@
         <description>Semicolon-separated authentication configs.</description>
         <placeholder>auth=SIMPLE</placeholder>
         <default-value>auth=SIMPLE</default-value>
+        <label>WebHDFS Authorization</label>
         <required>false</required>
     </parameter>
 
@@ -46,5 +52,14 @@
         <name>files</name>
         <service-class>org.apache.ambari.view.filebrowser.FileBrowserService</service-class>
     </resource>
-  
+
+    <auto-instance>
+        <name>AUTO_INSTANCE</name>
+        <label>Auto Create instance for the Files view</label>
+        <description>This view instance is auto created when the HDFS service is added to a cluster.</description>
+        <stack-id>HDP-2.*</stack-id>
+        <services>
+            <service>HDFS</service>
+        </services>
+    </auto-instance>
 </view>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java b/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
index 9fa3e9b..d481323 100644
--- a/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
+++ b/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/FilebrowserTest.java
@@ -41,6 +41,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileUtil;
 import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -108,7 +109,8 @@ public class FilebrowserTest{
     request.path = "/tmp1";
     fileBrowserService.fileOps().mkdir(request);
     Response response = fileBrowserService.fileOps().listdir("/");
-    JSONArray statuses = (JSONArray) response.getEntity();
+    JSONObject responseObject = (JSONObject) response.getEntity();
+    JSONArray statuses = (JSONArray) responseObject.get("files");
     System.out.println(response.getEntity());
     Assert.assertEquals(200, response.getStatus());
     Assert.assertTrue(statuses.size() > 0);
@@ -137,7 +139,8 @@ public class FilebrowserTest{
     Response response = uploadFile("/tmp/", "testUpload", ".tmp", "Hello world");
     Assert.assertEquals(200, response.getStatus());
     Response listdir = fileBrowserService.fileOps().listdir("/tmp");
-    JSONArray statuses = (JSONArray) listdir.getEntity();
+    JSONObject responseObject = (JSONObject) listdir.getEntity();
+    JSONArray statuses = (JSONArray) responseObject.get("files");
     System.out.println(statuses.size());
     Response response2 = fileBrowserService.download().browse("/tmp/testUpload.tmp", false, httpHeaders, uriInfo);
     Assert.assertEquals(200, response2.getStatus());

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ccaca98/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/HdfsServiceTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/HdfsServiceTest.java b/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/HdfsServiceTest.java
new file mode 100644
index 0000000..cc02a3f
--- /dev/null
+++ b/contrib/views/files/src/test/java/org/apache/ambari/view/filebrowser/HdfsServiceTest.java
@@ -0,0 +1,49 @@
+/**
+ * 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.view.filebrowser;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class HdfsServiceTest {
+  @Test
+  public void testNormalizeFsUrlWithoutProtocol() throws Exception {
+    String normalized = HdfsService.normalizeFsUrl("namenode.example.com:50070");
+    assertEquals(normalized, "webhdfs://namenode.example.com:50070");
+  }
+
+  @Test
+  public void testNormalizeFsUrlWithoutPort() throws Exception {
+    String normalized = HdfsService.normalizeFsUrl("webhdfs://namenode.example.com");
+    assertEquals(normalized, "webhdfs://namenode.example.com:50070");
+  }
+
+  @Test
+  public void testNormalizeFsUrlOnlyHostname() throws Exception {
+    String normalized = HdfsService.normalizeFsUrl("namenode.example.com");
+    assertEquals(normalized, "webhdfs://namenode.example.com:50070");
+  }
+
+  @Test
+  public void testNormalizeFsUrlFixNoCorrectUrl() throws Exception {
+    String normalized = HdfsService.normalizeFsUrl("webhdfs://namenode.example.com:50070");
+    assertEquals(normalized, "webhdfs://namenode.example.com:50070");
+  }
+}


[6/7] ambari git commit: AMBARI-11080. Fields in UI are not ordered even when specifying (category) index in site_properties.js (alexantonenko)

Posted by al...@apache.org.
AMBARI-11080. Fields in UI are not ordered even when specifying (category) index in site_properties.js (alexantonenko)


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

Branch: refs/heads/trunk
Commit: bcfffdb55ad182d8c816b45cd5df3fc7a13f2b74
Parents: f085f59
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 21:24:12 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 .../configs/service_configs_by_category_view.js |  8 ++-
 .../service_configs_by_category_view_test.js    | 62 ++++++++++++++++++++
 2 files changed, 68 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/bcfffdb5/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 ab2a498..2e9e6e5 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
@@ -44,9 +44,13 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
    * @type {Array}
    */
   categoryConfigs: function () {
-    var categoryConfigs = this.get('categoryConfigsAll');
+    // sort content type configs, sort the rest of configs based on index and then add content array at the end (as intended)
+    var categoryConfigs = this.get('categoryConfigsAll'),
+      contentOrderedArray = this.orderContentAtLast(categoryConfigs.filterProperty('displayType','content')),
+      contentFreeConfigs = categoryConfigs.filter(function(config) {return config.get('displayType')!=='content';}),
+      indexOrdered = this.sortByIndex(contentFreeConfigs);
 
-    return this.orderContentAtLast(this.sortByIndex(categoryConfigs)).filterProperty('isVisible', true);
+    return indexOrdered.concat(contentOrderedArray).filterProperty('isVisible', true);
   }.property('categoryConfigsAll.@each.isVisible').cacheable(),
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/bcfffdb5/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
index aeae18b..30f1749 100644
--- a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
+++ b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
@@ -521,4 +521,66 @@ describe('App.ServiceConfigsByCategoryView', function () {
 
   });
 
+  describe('#categoryConfigs', function () {
+    var view,
+      result = [1,2,3,4,5],
+      cases = [
+        {
+          categoryNname: 'TestCategory',
+          serviceConfigs: [
+            Em.Object.create({category: "TestCategory", index: 1, name: "a", isVisible: true, resultId: 1}),
+            Em.Object.create({category: "TestCategory", index: 2, name: "b", isVisible: true, resultId: 2}),
+            Em.Object.create({category: "TestCategory", index: 5, name: "c", isVisible: true, resultId: 5}),
+            Em.Object.create({category: "TestCategory", index: 4, name: "d", isVisible: true, resultId: 4}),
+            Em.Object.create({category: "TestCategory", index: 3, name: "e", isVisible: true, resultId: 3})
+          ],
+          title: 'Order by index with no content type'
+        },
+        {
+          categoryNname: 'TestCategory',
+          serviceConfigs: [
+            Em.Object.create({category: "TestCategory", index: 1, name: "a", isVisible: true, resultId: 1, displayType: 'int'}),
+            Em.Object.create({category: "TestCategory", index: 2, name: "b", isVisible: true, resultId: 4, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", index: 3, name: "c", isVisible: true, resultId: 2}),
+            Em.Object.create({category: "TestCategory", index: 4, name: "d", isVisible: true, resultId: 5, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", index: 5, name: "e", isVisible: true, resultId: 3})
+          ],
+          title: 'Order configs by index and display type equal to content'
+        },
+        {
+          categoryNname: 'TestCategory',
+          serviceConfigs: [
+            Em.Object.create({category: "TestCategory", name: "a", isVisible: true, resultId: 1, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", name: "b", isVisible: true, resultId: 2, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", name: "c", isVisible: true, resultId: 3, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", name: "d", isVisible: true, resultId: 4, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", name: "e", isVisible: true, resultId: 5, displayType: 'content'})
+          ],
+          title: 'Order configs by display type equal to content - so they will be sorted alphabetically'
+        },
+        {
+          categoryNname: 'TestCategory',
+          serviceConfigs: [
+            Em.Object.create({category: "TestCategory", index: 5, name: "a", isVisible: true, resultId: 1, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", index: 4, name: "b", isVisible: true, resultId: 2, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", index: 3, name: "c", isVisible: true, resultId: 3, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", index: 2, name: "d", isVisible: true, resultId: 4, displayType: 'content'}),
+            Em.Object.create({category: "TestCategory", index: 1, name: "e", isVisible: true, resultId: 5, displayType: 'content'})
+          ],
+          title: 'Order configs by display type equal to content - so they will be sorted alphabetically not by index'
+        }
+      ];
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        view = App.ServiceConfigsByCategoryView.create({
+          category: {
+            name: item.categoryNname
+          },
+          serviceConfigs: item.serviceConfigs
+        });
+        expect(view.get('categoryConfigs').mapProperty('resultId')).to.deep.equal(result);
+      });
+    });
+  });
 });


[7/7] ambari git commit: AMBARI-11077. Kerb: wizard should use non-button undo icon (alexantonenko)

Posted by al...@apache.org.
AMBARI-11077. Kerb: wizard should use non-button undo icon (alexantonenko)


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

Branch: refs/heads/trunk
Commit: bd8a5f98df2ec403480122a10b1d60d38f7507cc
Parents: 81a3eeb
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 20:46:01 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 ambari-web/app/styles/application.less                    |  4 ++++
 .../app/templates/common/configs/compare_property.hbs     |  2 +-
 .../templates/common/configs/notifications_configs.hbs    |  4 ++--
 .../app/templates/common/configs/overriddenProperty.hbs   |  4 ++--
 .../templates/common/configs/service_config_category.hbs  | 10 +++++-----
 .../widgets/comparison/config_widget_comparison.hbs       |  2 +-
 .../templates/main/alerts/create_alert_notification.hbs   |  2 +-
 ambari-web/app/views/common/controls_view.js              |  2 +-
 8 files changed, 17 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 1e8e6d4..806d356 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -480,6 +480,10 @@ h1 {
   }
 }
 
+.btn-small {
+  text-decoration: none !important;
+}
+
 .hide {
   visibility: hidden;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/templates/common/configs/compare_property.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/compare_property.hbs b/ambari-web/app/templates/common/configs/compare_property.hbs
index a5e17dd..f593825 100644
--- a/ambari-web/app/templates/common/configs/compare_property.hbs
+++ b/ambari-web/app/templates/common/configs/compare_property.hbs
@@ -25,7 +25,7 @@
       {{/if}}
       {{#unless compareConfig.isMock}}
         {{#if compareConfig.supportsFinal}}
-            <a disabled="disabled" {{bindAttr class=":btn :btn-small :btn-final compareConfig.isFinal:active compareConfig.hideFinalIcon:hidden" }}>
+            <a disabled="disabled" {{bindAttr class=":btn-small :btn-final compareConfig.isFinal:active compareConfig.hideFinalIcon:hidden" }}>
                 <i class="icon-lock"></i>
             </a>
         {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/templates/common/configs/notifications_configs.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/notifications_configs.hbs b/ambari-web/app/templates/common/configs/notifications_configs.hbs
index 27d1820..d58d076 100644
--- a/ambari-web/app/templates/common/configs/notifications_configs.hbs
+++ b/ambari-web/app/templates/common/configs/notifications_configs.hbs
@@ -48,7 +48,7 @@
               {{#if isRemovable}}
                 {{#isAccessible ADMIN}}
                   {{#unless this.isComparison}}
-                    <a class="btn btn-small" href="#" data-toggle="tooltip"
+                    <a class="btn-small" href="#" data-toggle="tooltip"
                       {{action "removeProperty" this target="view"}}
                       {{translateAttr data-original-title="common.remove"}}>
                       <i class="icon-minus-sign"></i>
@@ -71,7 +71,7 @@
       <div class="entry-row indent-1">
         {{view Ember.RadioButton name="tlsOrSsl" disabledBinding="view.configsAreDisabled" selectionBinding="view.tlsOrSsl" value="ssl"}} {{t installer.step7.misc.notification.use_ssl}}
       </div>
-      
+
       {{#isAccessible ADMIN}}
         {{#if view.canEdit}}
           {{#unless view.configsAreDisabled}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/templates/common/configs/overriddenProperty.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/overriddenProperty.hbs b/ambari-web/app/templates/common/configs/overriddenProperty.hbs
index d9d8dd2..9484f7e 100644
--- a/ambari-web/app/templates/common/configs/overriddenProperty.hbs
+++ b/ambari-web/app/templates/common/configs/overriddenProperty.hbs
@@ -21,7 +21,7 @@
     {{view overriddenSCP.viewClass serviceConfigBinding="overriddenSCP" categoryConfigsBinding="view.categoryConfigs"}}
     {{#if overriddenSCP.supportsFinal}}
       <a href="#" data-toggle="tooltip"
-        {{bindAttr class=":btn :btn-small :btn-final overriddenSCP.isFinal:active overriddenSCP.hideFinalIcon:hidden" disabled="overriddenSCP.isNotEditable"}}
+        {{bindAttr class=":btn-small :btn-final overriddenSCP.isFinal:active overriddenSCP.hideFinalIcon:hidden" disabled="overriddenSCP.isNotEditable"}}
         {{action "toggleFinalFlag" overriddenSCP target="view"}}
         {{translateAttr data-original-title="services.service.config.final"}}>
         <i class="icon-lock"></i>
@@ -36,7 +36,7 @@
     {{else}}
       {{#if overriddenSCP.isEditable}}
         {{#if isNotDefaultValue}}
-          <a class="btn btn-small" href="#" data-toggle="tooltip"
+          <a class="btn-small" href="#" data-toggle="tooltip"
             {{action "doRestoreDefaultValue" overriddenSCP target="view"}}
             {{translateAttr data-original-title="common.undo"}}>
             <i class="icon-undo"></i>

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/templates/common/configs/service_config_category.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config_category.hbs b/ambari-web/app/templates/common/configs/service_config_category.hbs
index fbc5c2a..a69fca0 100644
--- a/ambari-web/app/templates/common/configs/service_config_category.hbs
+++ b/ambari-web/app/templates/common/configs/service_config_category.hbs
@@ -68,7 +68,7 @@
                 {{/if}}
                 {{#if supportsFinal}}
                   <a href="#" data-toggle="tooltip"
-                    {{bindAttr class=":btn :btn-small :btn-final isFinal:active hideFinalIcon:hidden" disabled="isNotEditable"}}
+                    {{bindAttr class=":btn-small :btn-final isFinal:active hideFinalIcon:hidden" disabled="isNotEditable"}}
                     {{action "toggleFinalFlag" this target="view"}}
                     {{translateAttr data-original-title="services.service.config.final"}}>
                     <i class="icon-lock"></i>
@@ -79,7 +79,7 @@
                     {{#if view.supportsHostOverrides}}
                       {{#isAccessible ADMIN}}
                         {{#unless this.isComparison}}
-                          <a class="btn btn-small" href="#" data-toggle="tooltip"
+                          <a class="btn-small" href="#" data-toggle="tooltip"
                             {{action "createOverrideProperty" this target="view"}}
                             {{translateAttr data-original-title="common.override"}}>
                             <i class="icon-plus-sign"></i>
@@ -90,7 +90,7 @@
                   {{/if}}
                   {{#unless cantBeUndone}}
                     {{#if isNotDefaultValue}}
-                      <a class="btn btn-small" href="#" data-toggle="tooltip"
+                      <a class="btn-small" href="#" data-toggle="tooltip"
                         {{action "doRestoreDefaultValue" this target="view"}}
                         {{translateAttr data-original-title="common.undo"}}>
                         <i class="icon-undo"></i>
@@ -100,7 +100,7 @@
                   {{#if isRemovable}}
                     {{#isAccessible ADMIN}}
                       {{#unless this.isComparison}}
-                        <a class="btn btn-small" href="#" data-toggle="tooltip"
+                        <a class="btn-small" href="#" data-toggle="tooltip"
                           {{action "removeProperty" this target="view"}}
                           {{translateAttr data-original-title="common.remove"}}>
                           <i class="icon-minus-sign"></i>
@@ -118,7 +118,7 @@
                   {{/unless}}
                   {{#if isEditable}}
                     {{#if recommendedValueExists}}
-                      <a class="btn btn-small" href="#" data-toggle="tooltip"
+                      <a class="btn-small" href="#" data-toggle="tooltip"
                         {{action "setRecommendedValue" this target="view"}}
                         {{translateAttr data-original-title="services.service.config.setRecommendedValue"}}>
                         <i class="icon-repeat"></i>

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/templates/common/configs/widgets/comparison/config_widget_comparison.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/widgets/comparison/config_widget_comparison.hbs b/ambari-web/app/templates/common/configs/widgets/comparison/config_widget_comparison.hbs
index f5860f3..cab83c3 100644
--- a/ambari-web/app/templates/common/configs/widgets/comparison/config_widget_comparison.hbs
+++ b/ambari-web/app/templates/common/configs/widgets/comparison/config_widget_comparison.hbs
@@ -27,7 +27,7 @@
       {{/if}}
       {{#unless compareConfig.isMock}}
         {{#if compareConfig.supportsFinal}}
-          <a disabled="disabled" {{bindAttr class=":btn :btn-small :btn-final compareConfig.isFinal:active compareConfig.hideFinalIcon:hidden" }}>
+          <a disabled="disabled" {{bindAttr class=":btn-small :btn-final compareConfig.isFinal:active compareConfig.hideFinalIcon:hidden" }}>
             <i class="icon-lock"></i>
           </a>
         {{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/create_alert_notification.hbs b/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
index 647ba98..0a83f63 100644
--- a/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
+++ b/ambari-web/app/templates/main/alerts/create_alert_notification.hbs
@@ -242,7 +242,7 @@
 
         <div class="controls">
           {{view Em.TextField valueBinding="customProperty.value" class="input-xlarge"}}
-          <a href="#" {{action "removeCustomPropertyHandler" customProperty target="controller"}} class="btn btn-small"><span class="icon-minus-sign"></span></a>
+          <a href="#" {{action "removeCustomPropertyHandler" customProperty target="controller"}} class="btn-small"><span class="icon-minus-sign"></span></a>
         </div>
       </div>
     {{/each}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd8a5f98/ambari-web/app/views/common/controls_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js
index 2b29ebc..3bafde1 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -1576,7 +1576,7 @@ App.CheckDBConnectionView = Ember.View.extend({
  */
 App.BaseUrlTextField = Ember.TextField.extend({
 
-  layout: Ember.Handlebars.compile('<div class="pull-left">{{yield}}</div> {{#if view.valueWasChanged}}<div class="pull-right"><a class="btn btn-small" {{action "restoreValue" target="view"}}><i class="icon-undo"></i></a></div>{{/if}}'),
+  layout: Ember.Handlebars.compile('<div class="pull-left">{{yield}}</div> {{#if view.valueWasChanged}}<div class="pull-right"><a class="btn-small" {{action "restoreValue" target="view"}}><i class="icon-undo"></i></a></div>{{/if}}'),
 
   /**
    * Binding in the template


[5/7] ambari git commit: AMBARI-11075. Apply a property value in hdfs-site when ranger-hdfs-plugin is enabled (alexantonenko)

Posted by al...@apache.org.
AMBARI-11075. Apply a property value in hdfs-site when ranger-hdfs-plugin is enabled (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 81a3eebdd47c4c0179d3af2f5c45baf69a474db7
Parents: 17f4eca
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 20:30:29 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 .../utils/configs/modification_handlers/hdfs.js |  18 +++
 .../configs/service_configs_by_category_view.js |  89 ++++++-----
 .../service_configs_by_category_view_test.js    | 151 +++++++++++++++++++
 ambari-web/test/views/main/host_test.js         |   2 +-
 4 files changed, 223 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/81a3eebd/ambari-web/app/utils/configs/modification_handlers/hdfs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/modification_handlers/hdfs.js b/ambari-web/app/utils/configs/modification_handlers/hdfs.js
index 128b62b..bff1ddd 100644
--- a/ambari-web/app/utils/configs/modification_handlers/hdfs.js
+++ b/ambari-web/app/utils/configs/modification_handlers/hdfs.js
@@ -34,9 +34,12 @@ module.exports = App.ServiceConfigModificationHandler.create({
     var affectedPropertyName = changedConfig.get("name");
     if (affectedPropertyName == rangerPluginEnabledName) {
       var configDfsPermissionsEnabled = this.getConfig(allConfigs, 'dfs.permissions.enabled', 'hdfs-site.xml', 'HDFS');
+      var configAttributesProviderClass = this.getConfig(allConfigs, 'dfs.namenode.inode.attributes.provider.class', 'hdfs-site.xml', 'HDFS');
+      var isAttributesProviderClassSet = typeof configAttributesProviderClass !== 'undefined';
 
       var rangerPluginEnabled = newValue == "Yes";
       var newDfsPermissionsEnabled = rangerPluginEnabled ? "true" : "true";
+      var newAttributesProviderClass = 'org.apache.ranger.authorization.hadoop.RangerHdfsAuthorizer';
 
       // Add Hive-Ranger configs
       if (configDfsPermissionsEnabled != null && newDfsPermissionsEnabled !== configDfsPermissionsEnabled.get('value')) {
@@ -52,6 +55,21 @@ module.exports = App.ServiceConfigModificationHandler.create({
           filename : 'hdfs-site.xml'
         });
       }
+      if (rangerPluginEnabled && (!isAttributesProviderClassSet || newAttributesProviderClass != configAttributesProviderClass.get('value'))) {
+        affectedProperties.push({
+          serviceName : "HDFS",
+          sourceServiceName : "HDFS",
+          propertyName : 'dfs.namenode.inode.attributes.provider.class',
+          propertyDisplayName : 'dfs.namenode.inode.attributes.provider.class',
+          newValue : newAttributesProviderClass,
+          curValue : isAttributesProviderClassSet ? configAttributesProviderClass.get('value') : '',
+          changedPropertyName : rangerPluginEnabledName,
+          removed : false,
+          isNewProperty : !isAttributesProviderClassSet,
+          filename : 'hdfs-site.xml',
+          categoryName: 'Custom hdfs-site'
+        });
+      }
     }
     return affectedProperties;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/81a3eebd/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 85402f0..ab2a498 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
@@ -162,9 +162,20 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
         header: "Warning: you must also change these Service properties",
         onApply: function () {
           self.get("newAffectedProperties").forEach(function(item) {
-            self.get("controller.stepConfigs").findProperty("serviceName", item.serviceName).get("configs").find(function(config) {
-              return item.propertyName == config.get('name') && (item.filename == null || item.filename == config.get('filename'));
-            }).set("value", item.newValue);
+            if (item.isNewProperty) {
+              self.createProperty({
+                name: item.propertyName,
+                displayName: item.propertyDisplayName,
+                value: item.newValue,
+                categoryName: item.categoryName,
+                serviceName: item.serviceName,
+                filename: item.filename
+              });
+            } else {
+              self.get("controller.stepConfigs").findProperty("serviceName", item.serviceName).get("configs").find(function(config) {
+                return item.propertyName == config.get('name') && (item.filename == null || item.filename == config.get('filename'));
+              }).set("value", item.newValue);
+            }
           });
           self.get("controller").set("miscModalVisible", false);
           this.hide();
@@ -354,6 +365,34 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
     return 'admin-bulk-add-properties-' + App.router.get('loginName');
   },
 
+  isSecureConfig: function (configName, filename) {
+    var secureConfigs = this.get('controller.secureConfigs').filterProperty('filename', filename);
+    return !!secureConfigs.findProperty('name', configName);
+  },
+
+  createProperty: function (propertyObj) {
+    var selectedConfigGroup = this.get('controller.selectedConfigGroup'),
+      isSecureConfig = this.isSecureConfig(propertyObj.name, propertyObj.filename);
+    this.get('serviceConfigs').pushObject(App.ServiceConfigProperty.create({
+      name: propertyObj.name,
+      displayName: propertyObj.displayName || propertyObj.name,
+      value: propertyObj.value,
+      displayType: stringUtils.isSingleLine(propertyObj.value) ? 'advanced' : 'multiLine',
+      isSecureConfig: isSecureConfig,
+      category: propertyObj.categoryName,
+      id: 'site property',
+      serviceName: propertyObj.serviceName,
+      defaultValue: null,
+      supportsFinal: App.config.shouldSupportFinal(propertyObj.serviceName, propertyObj.filename),
+      filename: propertyObj.filename || '',
+      isUserProperty: true,
+      isNotSaved: true,
+      isRequired: false,
+      group: selectedConfigGroup.get('isDefault') ? null : selectedConfigGroup,
+      isOverridable: selectedConfigGroup.get('isDefault')
+    }));
+  },
+
   /**
    * Show popup for adding new config-properties
    * @method showAddPropertyWindow
@@ -375,44 +414,13 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
         var service = this.get('service');
         var serviceName = service.get('serviceName');
 
-        var secureConfigs = this.get('controller.secureConfigs').filterProperty('filename', siteFileName);
-
-        function isSecureConfig(configName) {
-          return !!secureConfigs.findProperty('name', configName);
-        }
-
         var configsOfFile = service.get('configs').filterProperty('filename', siteFileName);
         var siteFileProperties = App.config.get('configMapping').all().filterProperty('filename', siteFileName);
 
-        var supportsFinal = App.config.shouldSupportFinal(serviceName, siteFileName);
-
         function isDuplicatedConfigKey(name) {
           return siteFileProperties.findProperty('name', name) || configsOfFile.findProperty('name', name);
         }
 
-        var serviceConfigs = this.get('serviceConfigs');
-
-        function createProperty(propertyName, propertyValue) {
-          serviceConfigs.pushObject(App.ServiceConfigProperty.create({
-            name: propertyName,
-            displayName: propertyName,
-            value: propertyValue,
-            displayType: stringUtils.isSingleLine(propertyValue) ? 'advanced' : 'multiLine',
-            isSecureConfig: isSecureConfig(propertyName),
-            category: category.get('name'),
-            id: 'site property',
-            serviceName: serviceName,
-            defaultValue: null,
-            supportsFinal: supportsFinal,
-            filename: siteFileName || '',
-            isUserProperty: true,
-            isNotSaved: true,
-            isRequired: false,
-            group: selectedConfigGroup.get('isDefault') ? null : selectedConfigGroup,
-            isOverridable: selectedConfigGroup.get('isDefault')
-          }));
-        }
-
         var serviceConfigObj = Ember.Object.create({
           isBulkMode: isBulkMode,
           bulkConfigValue: '',
@@ -501,6 +509,11 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
           primary: 'Add',
           secondary: 'Cancel',
           onPrimary: function () {
+            var propertyObj = {
+              filename: siteFileName,
+              serviceName: serviceName,
+              categoryName: category.get('name')
+            };
             if (serviceConfigObj.isBulkMode) {
               var popup = this;
               processConfig(serviceConfigObj.bulkConfigValue, function (error, parsedConfig) {
@@ -510,7 +523,9 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
                 } else {
                   for (var key in parsedConfig) {
                     if (parsedConfig.hasOwnProperty(key)) {
-                      createProperty(key, parsedConfig[key]);
+                      propertyObj.name = key;
+                      propertyObj.value = parsedConfig[key];
+                      persistController.createProperty(propertyObj);
                     }
                   }
                   popup.hide();
@@ -523,7 +538,9 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, App.ConfigOverri
                * For the first entrance use this if (serviceConfigObj.name.trim() != '')
                */
               if (!serviceConfigObj.isKeyError) {
-                createProperty(serviceConfigObj.get('name'), serviceConfigObj.get('value'));
+                propertyObj.name = serviceConfigObj.get('name');
+                propertyObj.value = serviceConfigObj.get('value');
+                persistController.createProperty(propertyObj);
                 this.hide();
               }
             }

http://git-wip-us.apache.org/repos/asf/ambari/blob/81a3eebd/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
index 6505cf0..aeae18b 100644
--- a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
+++ b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
@@ -370,4 +370,155 @@ describe('App.ServiceConfigsByCategoryView', function () {
     });
   });
 
+  describe('#isSecureConfig', function () {
+
+    var cases = [
+      {
+        name: 'n0',
+        filename: 'f0',
+        isSecureConfig: true,
+        title: 'secure config'
+      },
+      {
+        name: 'n1',
+        filename: 'f1',
+        isSecureConfig: false,
+        title: 'secure config with the same name is present in another filename'
+      },
+      {
+        name: 'n2',
+        filename: 'f2',
+        isSecureConfig: false,
+        title: 'no configs of the specified filename are secure'
+      }
+    ];
+
+    before(function () {
+      view.reopen({
+        controller: {
+          secureConfigs: [
+            {
+              name: 'n0',
+              filename: 'f0'
+            },
+            {
+              name: 'n1',
+              filename: 'f0'
+            },
+            {
+              name: 'n2',
+              filename: 'f1'
+            }
+          ]
+        }
+      })
+    });
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        expect(view.isSecureConfig(item.name, item.filename)).to.equal(item.isSecureConfig);
+      });
+    });
+
+  });
+
+  describe('#createProperty', function () {
+
+    var cases = [
+      {
+        propertyObj: {
+          name: 'n0',
+          displayName: 'd0',
+          value: 'v0',
+          filename: 'f0',
+          categoryName: 'c0',
+          serviceName: 's0'
+        },
+        isDefaultConfigGroup: true,
+        result: {
+          name: 'n0',
+          displayName: 'd0',
+          value: 'v0',
+          displayType: 'advanced',
+          isSecureConfig: true,
+          category: 'c0',
+          id: 'site property',
+          serviceName: 's0',
+          defaultValue: null,
+          supportsFinal: true,
+          filename: 'f0',
+          isUserProperty: true,
+          isNotSaved: true,
+          isRequired: false,
+          group: null,
+          isOverridable: true
+        },
+        title: 'single line value, secure config, final attribute supported, default config group'
+      },
+      {
+        propertyObj: {
+          name: 'n1',
+          value: 'v\n1',
+          filename: '',
+          categoryName: 'c1',
+          serviceName: 's1'
+        },
+        isDefaultConfigGroup: false,
+        result: {
+          name: 'n1',
+          displayName: 'n1',
+          value: 'v\n1',
+          displayType: 'multiLine',
+          isSecureConfig: false,
+          category: 'c1',
+          id: 'site property',
+          serviceName: 's1',
+          defaultValue: null,
+          supportsFinal: false,
+          filename: '',
+          isUserProperty: true,
+          isNotSaved: true,
+          isRequired: false,
+          group: Em.Object.create({
+            isDefault: false
+          }),
+          isOverridable: false
+        },
+        title: 'multiline value, non-secure config, no display name and filename, final attribute not supported, custom config group'
+      }
+    ];
+
+    before(function () {
+      view.get('serviceConfigs').clear();
+      sinon.stub(view, 'isSecureConfig').withArgs('n0', 'f0').returns(true).withArgs('n1', '').returns(false);
+      sinon.stub(App.config, 'shouldSupportFinal').withArgs('s0', 'f0').returns(true).withArgs('s1', '').returns(false);
+    });
+
+    after(function () {
+      view.get('serviceConfigs').clear();
+      view.isSecureConfig.restore();
+      App.config.shouldSupportFinal.restore();
+    });
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        view.reopen({
+          filteredCategoryConfigs: [],
+          controller: {
+            selectedConfigGroup: Em.Object.create({
+              isDefault: item.isDefaultConfigGroup
+            })
+          }
+        });
+        view.createProperty(item.propertyObj);
+        expect(view.get('serviceConfigs').filterProperty('name', item.propertyObj.name)).to.have.length(1);
+        expect(view.get('serviceConfigs').findProperty('name', item.propertyObj.name).getProperties([
+          'name', 'displayName', 'value', 'displayType', 'isSecureConfig', 'category', 'id', 'serviceName', 'defaultValue',
+          'supportsFinal', 'filename', 'isUserProperty', 'isNotSaved', 'isRequired', 'group', 'isOverridable'
+        ])).to.eql(item.result);
+      });
+    });
+
+  });
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/81a3eebd/ambari-web/test/views/main/host_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host_test.js b/ambari-web/test/views/main/host_test.js
index 28871b7..8a0624b 100644
--- a/ambari-web/test/views/main/host_test.js
+++ b/ambari-web/test/views/main/host_test.js
@@ -98,7 +98,7 @@ describe('App.MainHostView', function () {
       view.updatePagination.restore();
     });
 
-    it('should execute and updatePagination', function () {
+    it('should execute updatePagination', function () {
       view.updateHostsPagination();
       expect(view.updatePagination.calledOnce).to.be.true;
     });


[3/7] ambari git commit: AMBARI-11074. UI - Removing config group overrides and saving doesn't save changes as they are still pending in UI (alexantonenko)

Posted by al...@apache.org.
AMBARI-11074. UI - Removing config group overrides and saving doesn't save changes as they are still pending in UI (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 17f4eca6daccdc5b5963f15cb0811a6d11fceca6
Parents: 7ccaca9
Author: Alex Antonenko <hi...@gmail.com>
Authored: Tue May 12 20:19:11 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Tue May 12 23:48:37 2015 +0300

----------------------------------------------------------------------
 ambari-web/app/mixins/common/configs/configs_saver.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/17f4eca6/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 01d9997..816af7a 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -120,7 +120,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
 
           var overridenConfigs = this.getConfigsForGroup(configs, configGroup.get('name'));
 
-          if (Em.isArray(overridenConfigs) && overridenConfigs.length) {
+          if (Em.isArray(overridenConfigs)) {
             this.saveGroup(overridenConfigs, configGroup, this.get('content.serviceName') === serviceName);
           }
         }
@@ -1250,4 +1250,4 @@ App.ConfigsSaverMixin = Em.Mixin.create({
         return value;
     }
   }
-});
\ No newline at end of file
+});