فهرست منبع

AMBARI-1003. Nagios sections should use backend API to populate. (Srimanth Gunturi via yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418918 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 سال پیش
والد
کامیت
2d91266ab9

+ 3 - 0
AMBARI-666-CHANGES.txt

@@ -401,6 +401,9 @@ AMBARI-666 branch (unreleased changes)
 
   IMPROVEMENTS
 
+  AMBARI-1003. Nagios sections should use backend API to populate. (Srimanth
+  Gunturi via yusaku)
+
   AMBARI-1062. Convert Apache license header comment style in Handlebars files
   to Handlebars comments rather than JavaScript comments. (yusaku)
 

+ 430 - 0
ambari-web/app/assets/data/alerts/alerts.jsonp

@@ -0,0 +1,430 @@
+jQuery172040994187095202506_1352498338217({
+   "alerts":[
+      {
+         "service_description":"Process down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"1",
+         "plugin_output":"TCP OK - 0.002 second response time on port 50010",
+         "last_hard_state_change":"1350378326",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Storage full",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: Capacity:[], Remaining Capacity:[], percent_full:[0]",
+         "last_hard_state_change":"1350378331",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498195",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498195",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Ganglia [gmetad] Process down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.003 second response time on port 8651",
+         "last_hard_state_change":"1350378335",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Ganglia collector [gmond] Process down alert for jobtracker",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.006 second response time on port 8662",
+         "last_hard_state_change":"1350378340",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Ganglia collector [gmond] Process down alert for namenode",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.005 second response time on port 8661",
+         "last_hard_state_change":"1350378344",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Ganglia collector [gmond] Process down alert for slaves",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.001 second response time on port 8660",
+         "last_hard_state_change":"1350378349",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Corrupt\/Missing blocks",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: corrupt_blocks:<0>, missing_blocks:<0>, total_blocks:<135>",
+         "last_hard_state_change":"1350933589",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498193",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"1350933469",
+         "is_flapping":"0",
+         "last_check":"1352498193",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"HDFS Capacity utilization",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: DFSUsedGB:<0>, DFSTotalGB:<784.3>",
+         "last_hard_state_change":"1350378358",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498195",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498195",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Namenode RPC Latency",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: RpcQueueTime_avg_time:<0> Secs, RpcProcessingTime_avg_time:<0> Secs",
+         "last_hard_state_change":"1350378362",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498195",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498195",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Percent DataNodes down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: total:<1>, affected:<0>",
+         "last_hard_state_change":"1350378367",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Percent DataNodes storage full",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"1",
+         "plugin_output":"OK: total:<1>, affected:<0>",
+         "last_hard_state_change":"1350378371",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498193",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498193",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"JobHistory Web UI down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: Successfully accessed jobhistory Web UI",
+         "last_hard_state_change":"1350378376",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"1351216729",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"MAPREDUCE"
+      },
+      {
+         "service_description":"JobTracker Web UI down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"1",
+         "plugin_output":"OK: Successfully accessed jobtracker Web UI",
+         "last_hard_state_change":"1350378380",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"1351216729",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"MAPREDUCE"
+      },
+      {
+         "service_description":"Jobtracker CPU utilization",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"2 CPU, average load 3.5% < 200% : OK",
+         "last_hard_state_change":"1350378385",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498195",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498195",
+         "service_type":"MAPREDUCE"
+      },
+      {
+         "service_description":"Jobtracker Process down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.001 second response time on port 50030",
+         "last_hard_state_change":"1351216775",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"1351216745",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"MAPREDUCE"
+      },
+      {
+         "service_description":"JobTracker RPC Latency",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: RpcQueueTime_avg_time:<0.03> Secs, RpcProcessingTime_avg_time:<0> Secs",
+         "last_hard_state_change":"1350378394",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498195",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498195",
+         "service_type":"MAPREDUCE"
+      },
+      {
+         "service_description":"Percent TaskTrackers down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: total:<1>, affected:<0>",
+         "last_hard_state_change":"1351216880",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"1351216850",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"MAPREDUCE"
+      },
+      {
+         "service_description":"Nagios status log staleness",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"NAGIOS OK: 2 processes, status log updated 0 seconds ago",
+         "last_hard_state_change":"1350937033",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498233",
+         "last_time_warning":"1350936733",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498233",
+         "service_type":"UNKNOWN"
+      },
+      {
+         "service_description":"Namenode Edit logs directory status",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: All Namenode directories are active",
+         "last_hard_state_change":"1350378408",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Namenode Host CPU utilization",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"2 CPU, average load 3.5% < 200% : OK",
+         "last_hard_state_change":"1350378412",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498212",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498212",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Namenode Process down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.001 second response time on port 8020",
+         "last_hard_state_change":"1350378417",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Namenode Web UI down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: Successfully accessed namenode Web UI",
+         "last_hard_state_change":"1350378421",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Secondary Namenode Process down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.001 second response time on port 50090",
+         "last_hard_state_change":"1350378426",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498284",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498284",
+         "service_type":"HDFS"
+      },
+      {
+         "service_description":"Oozie status check",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"OK: Oozie server status [System mode: NORMAL]",
+         "last_hard_state_change":"1351217029",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"1351924129",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"OOZIE"
+      },
+      {
+         "service_description":"Puppet agent down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"0",
+         "plugin_output":"TCP OK - 0.001 second response time on port 8139",
+         "last_hard_state_change":"1350378435",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"0",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"PUPPET"
+      },
+      {
+         "service_description":"Process down",
+         "host_name":"hostname",
+         "current_attempt":"1",
+         "current_state":"1",
+         "plugin_output":"TCP OK - 0.005 second response time on port 50060",
+         "last_hard_state_change":"1351216849",
+         "last_hard_state":"0",
+         "last_time_ok":"1352498253",
+         "last_time_warning":"0",
+         "last_time_unknown":"0",
+         "last_time_critical":"1351216789",
+         "is_flapping":"0",
+         "last_check":"1352498253",
+         "service_type":"UNKNOWN"
+      }
+   ],
+   "hostcounts":{
+      "up_hosts":1,
+      "down_hosts":0
+   },
+   "servicestates":{
+      "PUPPET":0,
+      "MAPREDUCE":"0",
+      "HDFS":"0",
+      "OOZIE":"0"
+   }
+});

+ 97 - 7
ambari-web/app/controllers/global/cluster_controller.js

@@ -69,7 +69,103 @@ App.ClusterController = Em.Controller.extend({
   getUrl: function(testUrl, url){
     return (App.testMode) ? testUrl: '/api/clusters/' + this.get('clusterName') + url;
   },
-   /**
+
+  /**
+   * Provides the URL to use for NAGIOS server. This URL
+   * is helpful in getting alerts data from server and also
+   * in populating links in UI. 
+   * 
+   * If null is returned, it means NAGIOS service is not installed.
+   */
+  nagiosUrl: function () {
+    if (App.testMode) {
+      return 'http://nagiosserver/nagios';
+    } else {
+      // We want live data here
+      var svcs = App.Service.find();
+      var nagiosSvc = svcs.findProperty("serviceName", "NAGIOS");
+      if (nagiosSvc) {
+        var svcComponents = nagiosSvc.get('components');
+        if (svcComponents) {
+          var nagiosSvcComponent = svcComponents.findProperty("componentName", "NAGIOS_SERVER");
+          if(nagiosSvcComponent){
+            var hostName = nagiosSvcComponent.get('host_name');
+            if(hostName){
+              return "http://"+hostName+"/nagios";
+            }
+          }
+        }
+      }
+      return null;
+    }
+  }.property('dataLoadList.services'),
+  
+  isNagiosInstalled: function(){
+    if(App.testMode){
+      return true;
+    }else{
+      var svcs = App.Service.find();
+      var nagiosSvc = svcs.findProperty("serviceName", "NAGIOS");
+      return nagiosSvc!=null;
+    }
+  }.property('dataLoadList.services'),
+  
+  /**
+   * Sorted list of alerts.
+   * Changes whenever alerts are loaded.
+   */
+  alerts: function(){
+    var alerts = App.Alert.find();
+    var alertsArray = alerts.toArray();
+    var sortedArray = alertsArray.sort(function(left, right){
+      var statusDiff = right.get('status') - left.get('status');
+      if(statusDiff==0){ // same error severity - sort by time
+        var rightTime = right.get('date');
+        var leftTime = left.get('time');
+        rightTime = rightTime ? rightTime.getTime() : 0;
+        leftTime = leftTime ? leftTime.getTime() : 0;
+        statusDiff = rightTime - leftTime;
+      }
+      return statusDiff;
+    });
+    return sortedArray;
+  }.property('dataLoadList.alerts'),
+  
+  /**
+   * This method automatically loads alerts when Nagios URL 
+   * changes. Once done it will trigger dataLoadList.alerts
+   * property, which will trigger the alerts property.
+   */
+  loadAlerts: function () {
+    var nagiosUrl = this.get('nagiosUrl');
+    if (nagiosUrl) {
+      var lastSlash = nagiosUrl.lastIndexOf('/');
+      if (lastSlash > -1) {
+        nagiosUrl = nagiosUrl.substring(0, lastSlash);
+      }
+      var dataUrl;
+      var ajaxOptions = {
+          dataType: "jsonp",
+          jsonp: "jsonp",
+          context: this,
+          complete: function (jqXHR, textStatus) {
+            this.updateLoadStatus('alerts')
+          }
+        };
+      if(App.testMode){
+        dataUrl = "/data/alerts/alerts.jsonp";
+        ajaxOptions.jsonpCallback = "jQuery172040994187095202506_1352498338217";
+      }else{
+        dataUrl = nagiosUrl + "/hdp/nagios/nagios_alerts.php?q1=alerts&alert_type=all";
+      }
+      App.HttpClient.get(dataUrl, App.alertsMapper, ajaxOptions);
+    }else{
+      this.updateLoadStatus('alerts');
+      console.log("No Nagios URL provided.")
+    }
+  }.observes('nagiosUrl'),
+  
+  /**
    *
    *  load all data and update load status
    */
@@ -79,7 +175,6 @@ App.ClusterController = Em.Controller.extend({
         return;
     }
 
-     var alertsUrl = "/data/alerts/alerts.json";
      var clusterUrl = this.getUrl('/data/clusters/cluster.json', '?fields=Clusters');
      var hostsUrl = this.getUrl('/data/hosts/hosts.json', '/hosts?fields=*');
      var servicesUrl = this.getUrl('/data/dashboard/services.json', '/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/host_components/*');
@@ -89,11 +184,6 @@ App.ClusterController = Em.Controller.extend({
 
      var racksUrl = "/data/racks/racks.json";
 
-    App.HttpClient.get(alertsUrl, App.alertsMapper,{
-      complete:function(jqXHR, textStatus){
-        self.updateLoadStatus('alerts');
-      }
-    });
     App.HttpClient.get(racksUrl, App.racksMapper,{
       complete:function(jqXHR, textStatus){
         self.updateLoadStatus('racks');

+ 16 - 8
ambari-web/app/controllers/main/dashboard.js

@@ -20,7 +20,9 @@ var App = require('app');
 
 App.MainDashboardController = Em.Controller.extend({
   name:'mainDashboardController',
-  alerts: App.Alert.find(),
+  alerts: function(){
+    return App.router.get('clusterController.alerts');
+  }.property('App.router.clusterController.alerts'),
   data: {
     HDFS:{
       "namenode_addr":"namenode:50070",
@@ -86,16 +88,12 @@ App.MainDashboardController = Em.Controller.extend({
   },
 
   services:function(){
-
-    /* TODO: create Lasy loading
-    setTimeout(function(){console.log(App.Service.find().objectAt(0).get("id"))}, 20);
-    */
     return App.router.get('mainServiceController.content');
   }.property('App.router.mainServiceController.content'),
   alertsFilteredBy: 'All',
   alertsFilter: function(event) {
     if (event.context)
-      this.set('alertsFilteredBy', event.context.get('label'));
+      this.set('alertsFilteredBy', event.context.get('serviceName'));
     else
       this.set('alertsFilteredBy', 'All');
   },
@@ -110,11 +108,21 @@ App.MainDashboardController = Em.Controller.extend({
     else
       var type = this.get('alertsFilteredBy').toLowerCase();
       return this.get('alerts').filter(function(item){
-        return item.get('serviceType').toLowerCase()==type;
+        var serviceType = item.get('serviceType');
+        return serviceType && serviceType.toLowerCase()==type.toLowerCase();
       });
   }.property('alerts', 'alertsFilteredBy'),
   
+  nagiosUrl: function(){
+    return App.router.get('clusterController.nagiosUrl');
+  }.property('App.router.clusterController.nagiosUrl'),
+  
+  isNagiosInstalled: function(){
+    return App.router.get('clusterController.isNagiosInstalled');
+  }.property('App.router.clusterController.isNagiosInstalled'),
+  
   alertsCount: function() {
-    return this.get('alerts').filterProperty('status', 'corrupt').length;
+    var alerts = this.get('alerts');
+    return alerts ? alerts.filterProperty('status', 'corrupt').length : 0;
   }.property('alerts')
 })

+ 14 - 3
ambari-web/app/controllers/main/service/info/summary.js

@@ -19,14 +19,25 @@ var App = require('app');
 
 App.MainServiceInfoSummaryController = Em.Controller.extend({
   name: 'mainServiceInfoSummaryController',
-  allAlerts: App.Alert.find(),
+  allAlerts: function(){
+    return App.router.get('clusterController.alerts');
+  }.property('App.router.clusterController.alerts'),
+
   alerts: function () {
     var serviceId = this.get('content.serviceName');
     if (serviceId) {
       return this.get('allAlerts').filter(function (item) {
-        return item.get('serviceType') && item.get('serviceType').toLowerCase() == serviceId;
+        return item.get('serviceType') && item.get('serviceType').toLowerCase() == serviceId.toLowerCase();
       });
     }
     return [];
-  }.property('allAlerts', 'content.serviceName')
+  }.property('allAlerts', 'content.serviceName'),
+  
+  nagiosUrl: function(){
+    return App.router.get('clusterController.nagiosUrl');
+  }.property('App.router.clusterController.nagiosUrl'),
+  
+  isNagiosInstalled: function(){
+    return App.router.get('clusterController.isNagiosInstalled');
+  }.property('App.router.clusterController.isNagiosInstalled')
 });

+ 13 - 5
ambari-web/app/mappers/server_data_mapper.js

@@ -59,20 +59,28 @@ App.QuickDataMapper = App.ServerDataMapper.extend({
 
   parseIt: function (data, config) {
     var result = {};
-    for (var i in config) {
+    for ( var i in config) {
       if (i.substr(0, 1) === '$') {
         i = i.substr(1, i.length);
         result[i] = config['$' + i];
       } else {
-        if (i.substr(-5) !== '_type' && i.substr(-4) !== '_key' && typeof config[i] == 'string') {
+        var isSpecial = false;
+        if (i.substr(-5) == '_type') {
+          var prefix = i.substr(0, i.length - 5);
+          isSpecial = config[prefix + '_key'] != null;
+        } else if (i.substr(-4) == '_key') {
+          var prefix = i.substr(0, i.length - 4);
+          isSpecial = config[prefix + '_type'] != null;
+        }
+        if (!isSpecial && typeof config[i] == 'string') {
           result[i] = this.getJsonProperty(data, config[i]);
         } else if (typeof config[i] == 'object') {
           result[i] = [];
-          var _data = this.getJsonProperty(data, config[i+'_key']);
+          var _data = this.getJsonProperty(data, config[i + '_key']);
           var _type = config[i + '_type'];
           var l = _data.length;
-          for (var index = 0; index < l; index++) {
-            if(_type == 'array'){
+          for ( var index = 0; index < l; index++) {
+            if (_type == 'array') {
               result[i].push(this.getJsonProperty(_data[index], config[i].item));
             } else {
               result[i].push(this.parseIt(_data[index], config[i]));

+ 8 - 8
ambari-web/app/models/alert.js

@@ -86,7 +86,7 @@ App.Alert = DS.Model.extend({
           return 'Hive';
       }
     }
-    return 'unknown';
+    return null;
   }.property('serviceType'),
 
   /**
@@ -97,20 +97,20 @@ App.Alert = DS.Model.extend({
       var type = this.get('serviceType').toLowerCase();
       switch (type) {
         case 'mapreduce':
-          return '#/main/services/2';
+          return '#/main/services/MAPREDUCE/summary';
         case 'hdfs':
-          return '#/main/services/1';
+          return '#/main/services/HDFS/summary';
         case 'hbase':
-          return '#/main/services/3';
+          return '#/main/services/HBASE/summary';
         case 'zookeeper':
-          return '#/main/services/4';
+          return '#/main/services/ZOOKEEPER/summary';
         case 'oozie':
-          return '#/main/services/5';
+          return '#/main/services/OOZIE/summary';
         case 'hive':
-          return '#/main/services/6';
+          return '#/main/services/HIVE/summary';
       }
     }
-    return '';
+    return null;
   }.property('serviceType')
 
 });

+ 3 - 1
ambari-web/app/styles/application.less

@@ -604,7 +604,9 @@ a:focus {
       padding-left: 7px;
     }
   }
-
+  .alert{
+    margin: 7px;
+  }
 }
 
 .go-to {

+ 40 - 28
ambari-web/app/templates/main/dashboard.hbs

@@ -68,42 +68,54 @@
         <h4>Alerts</h4>
         <div class="btn-group">
           <button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">{{controller.alertsFilteredBy}} <span class="caret"></span></button>
-          <a class="btn" href="http://nagiosserver/nagios" target="_blank" rel="tooltip" title="Go to Nagios"><i class="icon-link"></i></a>
+          <a class="btn" target="_blank" rel="tooltip" title="Go to Nagios" {{bindAttr href="controller.nagiosUrl"}}><i class="icon-link"></i></a>
           <ul class="dropdown-menu">
             <li><a {{action alertsFilter target="controller"}} href="javascript:void(null)">All</a></li>
             {{#each service in controller.services}}
-              <li><a {{action alertsFilter service target="controller"}} href="javascript:void(null)">{{service.label}}</a></li>
+              <li><a {{action alertsFilter service target="controller"}} href="javascript:void(null)">{{service.displayName}}</a></li>
             {{/each}}
           </ul>
         </div>
       </div>
       <ul class="alerts">
-        {{#each controller.displayAlerts}}
-        <li class="status-{{unbound status}}">
-          <div class="container-fluid">
-            <div class="row-fluid">
-              <div class="span1 status-icon">
-                {{#if isOk}}
-                  <i class="icon-ok icon-large"></i>
-                {{else}}
-                  <i class="icon-remove icon-large"></i>
-                {{/if}}
-              </div>
-              <div class="span11">
-                <div class="row-fluid">
-                  <div class="span8 title">{{title}}
-                    {{#if serviceName}}
-                      <a class="serviceLink" href="{{unbound serviceLink}}">{{serviceName}}</a>
-                    {{/if}}
-                  </div>
-                  <div class="span4 date-time">{{dateDisplay}}</div>
-                </div>
-                <div class="row-fluid message">{{message}}</div>
-              </div>
-            </div>
-          </div>
-        </li>
-        {{/each}}
+        {{#if controller.displayAlerts.length}}
+	        {{#each controller.displayAlerts}}
+		        <li class="status-{{unbound status}}">
+		          <div class="container-fluid">
+		            <div class="row-fluid">
+		              <div class="span1 status-icon">
+		                {{#if isOk}}
+		                  <i class="icon-ok icon-large"></i>
+		                {{else}}
+		                  <i class="icon-remove icon-large"></i>
+		                {{/if}}
+		              </div>
+		              <div class="span11">
+		                <div class="row-fluid">
+		                  <div class="span8 title">{{title}}
+		                    {{#if serviceLink}}
+		                      <a class="serviceLink" href="{{unbound serviceLink}}">{{serviceName}}</a>
+		                    {{/if}}
+		                  </div>
+		                  <div class="span4 date-time">{{dateDisplay}}</div>
+		                </div>
+		                <div class="row-fluid message">{{message}}</div>
+		              </div>
+		            </div>
+		          </div>
+		        </li>
+	        {{/each}}
+	      {{else}}
+	        {{#if controller.isNagiosInstalled}}
+	          <div class="alert alert-info">
+	            No alerts
+	          </div>
+	        {{else}}
+	          <div class="alert">
+	            Nagios service required for viewing alerts
+	          </div>
+	        {{/if}}
+	      {{/if}}
       </ul>
     </div>
 	</div>

+ 36 - 24
ambari-web/app/templates/main/service/info/summary.hbs

@@ -285,33 +285,45 @@
 		<div class="box-header">
 			<h4>Alerts</h4>
 			<div class="btn-group">
-        <a class="btn" href="http://nagiosserver/nagios" target="_blank" rel="tooltip" title="Go to Nagios"><i class="icon-link"></i></a>
+        <a class="btn" target="_blank" rel="tooltip" title="Go to Nagios" {{bindAttr href="controller.nagiosUrl"}}><i class="icon-link"></i></a>
 			</div>
 		</div>
 		<ul id='summary-alerts-list' class="alerts">
-			{{#each controller.alerts}}
-			 <li class="status-{{unbound status}}">
-          <div class="container-fluid">
-            <div class="row-fluid">
-              <div class="span1 status-icon">
-                {{#if isOk}}
-                  <i class="icon-ok icon-large"></i>
-                {{else}}
-                  <i class="icon-remove icon-large"></i>
-                {{/if}}
-              </div>
-              <div class="span11">
-                <div class="row-fluid">
-                  <div class="span7 title">{{title}}
-                  </div>
-                  <div class="span5 date-time">{{dateDisplay}}</div>
-                </div>
-                <div class="row-fluid message">{{message}}</div>
-              </div>
-            </div>
-          </div>
-        </li>
-			{{/each}}
+		  {{#if controller.alerts.length}}
+				{{#each controller.alerts}}
+				 <li class="status-{{unbound status}}">
+	          <div class="container-fluid">
+	            <div class="row-fluid">
+	              <div class="span1 status-icon">
+	                {{#if isOk}}
+	                  <i class="icon-ok icon-large"></i>
+	                {{else}}
+	                  <i class="icon-remove icon-large"></i>
+	                {{/if}}
+	              </div>
+	              <div class="span11">
+	                <div class="row-fluid">
+	                  <div class="span7 title">{{title}}
+	                  </div>
+	                  <div class="span5 date-time">{{dateDisplay}}</div>
+	                </div>
+	                <div class="row-fluid message">{{message}}</div>
+	              </div>
+	            </div>
+	          </div>
+	        </li>
+				{{/each}}
+			{{else}}
+		    {{#if controller.isNagiosInstalled}}
+			    <div class="alert alert-info">
+			      No alerts
+			    </div>
+			  {{else}}
+			    <div class="alert">
+			      Nagios service required for viewing alerts
+			    </div>
+			  {{/if}}
+			{{/if}}
 		</ul>
 	</div>
 </div>