You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2014/10/16 18:31:18 UTC
[2/4] git commit: AMBARI-7791. HBase Master CPU utilization alert is
not suppressed at MM (dlysnichenko)
AMBARI-7791. HBase Master CPU utilization alert is not suppressed at MM (dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/41b2d35f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/41b2d35f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/41b2d35f
Branch: refs/heads/branch-1.7.0
Commit: 41b2d35fd7c01ef2b95002b304cad5495ba7ea28
Parents: 9024fa4
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Mon Sep 1 19:17:32 2014 +0300
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Thu Oct 16 19:25:47 2014 +0300
----------------------------------------------------------------------
ambari-server/src/main/python/ambari-server.py | 2 +-
.../NAGIOS/package/files/check_wrapper.sh | 91 ----
.../services/NAGIOS/package/files/mm_wrapper.py | 326 +++++++++++++
.../package/scripts/nagios_server_config.py | 2 +-
.../package/templates/hadoop-commands.cfg.j2 | 38 +-
.../package/templates/hadoop-services.cfg.j2 | 13 -
.../NAGIOS/package/templates/nagios.cfg.j2 | 2 +-
.../package/files/check_checkpoint_time.py | 2 +-
.../NAGIOS/package/files/check_wrapper.sh | 94 ----
.../services/NAGIOS/package/files/mm_wrapper.py | 326 +++++++++++++
.../package/scripts/nagios_server_config.py | 2 +-
.../package/templates/hadoop-commands.cfg.j2 | 46 +-
.../package/templates/hadoop-services.cfg.j2 | 15 -
.../NAGIOS/package/templates/nagios.cfg.j2 | 2 +-
.../stacks/1.3.2/NAGIOS/test_mm_wrapper.py | 459 +++++++++++++++++++
.../stacks/1.3.2/NAGIOS/test_nagios_server.py | 8 +-
.../stacks/2.0.6/NAGIOS/test_mm_wrapper.py | 459 +++++++++++++++++++
.../stacks/2.0.6/NAGIOS/test_nagios_server.py | 10 +-
ambari-server/src/test/python/unitTests.py | 9 +-
19 files changed, 1632 insertions(+), 274 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/python/ambari-server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index 4988708..a36bb77 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -2939,7 +2939,7 @@ def status(args):
status, pid = is_server_runing()
if status:
print "Ambari Server running"
- print "Found Ambari Server PID: '" + str(pid) + " at: " + PID_DIR + os.sep + PID_NAME
+ print "Found Ambari Server PID: " + str(pid) + " at: " + PID_DIR + os.sep + PID_NAME
else:
print "Ambari Server not running. Stale PID File at: " + PID_DIR + os.sep + PID_NAME
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/check_wrapper.sh
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/check_wrapper.sh b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/check_wrapper.sh
deleted file mode 100644
index 8c36a79..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/check_wrapper.sh
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/bin/bash
-#
-#
-# 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.
-#
-#
-
-function real_service() {
- desc=$NAGIOS_SERVICEGROUPNAME
- eval "$1='$desc'"
-}
-
-function real_component() {
- arrDesc=(${NAGIOS_SERVICEDESC//::/ })
-
- compName="${arrDesc[0]}"
-
- case "$compName" in
- HBASEMASTER)
- realCompName="HBASE_MASTER"
- ;;
- REGIONSERVER)
- realCompName="HBASE_REGIONSERVER"
- ;;
- HIVE-METASTORE)
- realCompName="HIVE_METASTORE"
- ;;
- HIVE-SERVER)
- realCompName="HIVE_SERVER"
- ;;
- FLUME)
- realCompName="FLUME_SERVER"
- ;;
- HUE)
- realCompName="HUE_SERVER"
- ;;
- WEBHCAT)
- realCompName="WEBHCAT_SERVER"
- ;;
- *)
- realCompName=$compName
- ;;
- esac
-
- eval "$1='$realCompName'"
-}
-
-real_service_var=""
-real_service real_service_var
-
-real_comp_var=""
-real_component real_comp_var
-
-
-wrapper_output=`exec "$@"`
-wrapper_result=$?
-
-if [ "$wrapper_result" == "0" ]; then
- echo "$wrapper_output"
- exit $wrapper_result
-fi
-
-if [ ! -f /var/nagios/ignore.dat ]; then
- echo "$wrapper_output"
- exit $wrapper_result
-else
- count=$(grep $NAGIOS_HOSTNAME /var/nagios/ignore.dat | grep $real_service_var | grep $real_comp_var | wc -l)
- if [ "$count" -ne "0" ]; then
- echo "$wrapper_output\nAMBARIPASSIVE=${wrapper_result}" | sed 's/^[ \t]*//g'
- exit 0
- else
- echo "$wrapper_output"
- exit $wrapper_result
- fi
-fi
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/mm_wrapper.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/mm_wrapper.py b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/mm_wrapper.py
new file mode 100644
index 0000000..7a622b6
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/files/mm_wrapper.py
@@ -0,0 +1,326 @@
+#!/usr/bin/env python
+
+"""
+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.
+"""
+import sys
+import subprocess
+import os
+
+N_SGN = 'NAGIOS_SERVICEGROUPNAME'
+N_SD = 'NAGIOS_SERVICEDESC'
+N_HOST = 'NAGIOS_HOSTNAME'
+
+LIST_SEPARATOR = "--"
+HOSTNAME_PLACEHOLDER = "^^"
+IGNORE_DAT_FILE = "/var/nagios/ignore.dat"
+
+# Mode constants
+OR = 0
+AND = 1
+ENV_ONLY = 2
+FILTER_MM = 3
+LEGACY_CHECK_WRAPPER = 4
+MODES = ['or', 'and', 'env_only', 'filter_mm', 'legacy_check_wrapper']
+
+
+def ignored_host_list(service, component):
+ """
+ :param service: current service
+ :param component: current component
+ :return: all hosts where specified host component is in ignored state
+ """
+ try:
+ with open(IGNORE_DAT_FILE) as f:
+ lines = f.readlines()
+ except IOError:
+ return []
+ result = []
+ if lines:
+ for l in lines:
+ tokens = l.split(' ')
+ if len(tokens) == 3 and tokens[1] == service and tokens[2].strip() == component:
+ result.append(tokens[0])
+ return result
+
+
+def get_real_service():
+ try:
+ service = os.environ[N_SGN] # e.g. 'HBASE'
+ except KeyError:
+ service = ''
+ return service
+
+
+def get_real_component():
+ try:
+ arr_desc = os.environ[N_SD] # e.g. 'HBASE::Percent RegionServers live'
+ SEPARATOR = "::"
+ comp_name = arr_desc.replace(SEPARATOR, ' ').split(' ')[0]
+ except KeyError:
+ comp_name = ''
+ mapping = {
+ 'HBASEMASTER': 'HBASE_MASTER',
+ 'REGIONSERVER': 'HBASE_REGIONSERVER',
+ 'JOBHISTORY': 'MAPREDUCE2',
+ 'HIVE-METASTORE': 'HIVE_METASTORE',
+ 'HIVE-SERVER': 'HIVE_SERVER',
+ 'FLUME': 'FLUME_HANDLER',
+ 'HUE': 'HUE_SERVER',
+ 'WEBHCAT': 'WEBHCAT_SERVER',
+ }
+ if comp_name in mapping:
+ comp_name = mapping.get(comp_name)
+ return comp_name
+
+
+def check_output(*popenargs, **kwargs):
+ """
+ Imitate subprocess.check_output() for python 2.6
+ """
+ process = subprocess.Popen(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ *popenargs, **kwargs)
+ output, unused_err = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ err = subprocess.CalledProcessError(retcode, cmd)
+ # Monkey-patching for python 2.6
+ err.output = output
+ raise err
+ return output
+
+
+def print_usage():
+ """
+ Prints usage and exits with a non-zero exit code
+ """
+ print "Usage: mm_wrapper.py MODE HOST1 HOST2 .. HOSTN %s command arg1 arg2 .. argN" % LIST_SEPARATOR
+ print "MODE is one of the following: or, and, env_only, filter_mm, legacy_check_wrapper"
+ print "%s is a separator between list of hostnames and command with args" % LIST_SEPARATOR
+ print "%s is used as a hostname placeholder at command args" % HOSTNAME_PLACEHOLDER
+ print "Also script provides $MM_HOSTS shell variable to commands"
+ print "NOTE: Script makes use of Nagios-populated env vars %s and %s" % (N_SGN, N_SD)
+ print "For more info, please see docstrings at %s" % os.path.realpath(__file__)
+ sys.exit(1)
+
+
+def parse_args(args):
+ if not args or not LIST_SEPARATOR in args or args[0] not in MODES:
+ print_usage()
+ else:
+ mode = MODES.index(args[0]) # identify operation mode
+ args = args[1:] # Shift args left
+ hostnames = []
+ command_line = []
+ # Parse command line args
+ passed_separator = False # True if met LIST_SEPARATOR
+ for arg in args:
+ if not passed_separator:
+ if arg != LIST_SEPARATOR:
+ hostnames.append(arg)
+ else:
+ passed_separator = True
+ else:
+ if arg != LIST_SEPARATOR:
+ command_line.append(arg)
+ else: # Something definitely goes wrong
+ print "Could not parse arguments: " \
+ "There is more than one %s argument." % LIST_SEPARATOR
+ print_usage()
+
+ if not command_line:
+ print "No command provided."
+ print_usage()
+ return mode, hostnames, command_line
+
+
+def do_work(mode, hostnames, command_line):
+ # Execute commands
+ ignored_hosts = ignored_host_list(get_real_service(), get_real_component())
+ empty_check_result = {
+ 'message': 'No checks have been run (no hostnames provided)',
+ 'retcode': -1,
+ 'real_retcode': None
+ }
+ custom_env = os.environ.copy()
+ if ignored_hosts:
+ custom_env['MM_HOSTS'] = \
+ reduce(lambda a, b: "%s %s" % (a, b), ignored_hosts)
+ if mode == OR:
+ check_result = work_in_or_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result)
+ elif mode == AND:
+ check_result = work_in_and_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result)
+ elif mode == ENV_ONLY:
+ check_result = work_in_env_only_mode(hostnames, command_line, custom_env)
+ elif mode == FILTER_MM:
+ check_result = work_in_filter_mm_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result)
+ else: # mode == LEGACY_CHECK_WRAPPER:
+ check_result = work_in_legacy_check_wrapper_mode(ignored_hosts, command_line, custom_env)
+ # Build the final output
+ final_output = []
+ output = check_result.get('message')
+ if output is not None:
+ for string in output.splitlines():
+ final_output.append(string.strip())
+ real_retcode = check_result.get('real_retcode')
+ if real_retcode:
+ # This string is used at check_aggregate.php when aggregating alerts
+ final_output.append("AMBARIPASSIVE=%s" % real_retcode)
+ return final_output, check_result.get('retcode')
+
+
+def work_in_or_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result):
+ check_result = empty_check_result
+ for hostname in hostnames:
+ concrete_command_line = map( # Substitute hostname where needed
+ lambda x: hostname if x == HOSTNAME_PLACEHOLDER else x,
+ command_line)
+ try:
+ returncode = 0
+ real_retcode = None
+ message = check_output(concrete_command_line, env=custom_env)
+ except subprocess.CalledProcessError, e:
+ if hostname not in ignored_hosts:
+ returncode = e.returncode
+ else: # Host is in MM
+ real_retcode = e.returncode
+ message = e.output
+ really_positive_result = hostname not in ignored_hosts and returncode == 0
+ if check_result.get('retcode') <= returncode or really_positive_result:
+ check_result = {
+ 'message': message,
+ 'retcode': returncode,
+ 'real_retcode': real_retcode # Real (not suppressed) program retcode
+ }
+ if really_positive_result:
+ break # Exit on first real success
+ return check_result
+
+
+def work_in_and_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result):
+ check_result = empty_check_result
+ for hostname in hostnames:
+ concrete_command_line = map( # Substitute hostname where needed
+ lambda x: hostname if x == HOSTNAME_PLACEHOLDER else x,
+ command_line)
+ try:
+ returncode = 0
+ real_retcode = None
+ message = check_output(concrete_command_line, env=custom_env)
+ except subprocess.CalledProcessError, e:
+ if hostname not in ignored_hosts:
+ returncode = e.returncode
+ else:
+ real_retcode = e.returncode
+ message = e.output
+ if check_result.get('retcode') <= returncode:
+ check_result = {
+ 'message': message,
+ 'retcode': returncode,
+ 'real_retcode': real_retcode # Real (not suppressed) program retcode
+ }
+ return check_result
+
+
+def work_in_env_only_mode(hostnames, command_line, custom_env):
+ concrete_command_line = []
+ for item in command_line:
+ if item == HOSTNAME_PLACEHOLDER:
+ concrete_command_line.extend(hostnames)
+ else:
+ concrete_command_line.append(item)
+ try:
+ returncode = 0
+ message = check_output(concrete_command_line, env=custom_env)
+ except subprocess.CalledProcessError, e:
+ returncode = e.returncode
+ message = e.output
+ check_result = {
+ 'message': message,
+ 'retcode': returncode,
+ 'real_retcode': None # Real (not suppressed) program retcode
+ }
+ return check_result
+
+
+def work_in_filter_mm_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result):
+ not_mm_hosts = [hostname for hostname in hostnames if hostname not in ignored_hosts]
+ if not not_mm_hosts: # All hosts have been filtered
+ return empty_check_result
+ else:
+ return work_in_env_only_mode(not_mm_hosts, command_line, custom_env)
+
+
+def work_in_legacy_check_wrapper_mode(ignored_hosts, command_line, custom_env):
+ host = os.environ[N_HOST]
+ result = work_in_env_only_mode([host], command_line, custom_env)
+ real_retcode = result['retcode']
+ if host in ignored_hosts and real_retcode != 0: # Ignore fail
+ result['retcode'] = 0
+ result['real_retcode'] = real_retcode
+ return result
+
+
+def main():
+ """
+ This script allows to run nagios service check commands for host components
+ located at different hosts.
+ Also script passes to every command a $MM_HOSTS shell variable with a list of
+ hosts that are in MM
+
+ or mode: return 0 exit code if at least one service check succeeds.
+ Command exits on a first success.
+ Failures for host components that are in MM are suppressed (return code
+ is set to 0).
+ If command fails for all provided hostnames, script returns alert with the
+ greatest exit code value.
+
+ and mode:
+ Perform checks of all host components (effectively ignoring negative results
+ for MM components). If service check is successful for all hosts, script
+ also returns zero exit code. Otherwise alert with the greatest exit code is
+ returned.
+
+ env_only mode:
+ Pass list of all hosts to command and run it once. The only role of
+ mm_wrapper script in this mode is to provide properly initialized
+ $MM_HOSTS env variable to command being run. All duties of ignoring failures
+ of MM host components are delegated to a command being run.
+
+ filter_mm
+ Similar to env_only mode. The only difference is that hostnames for
+ host components that are in MM are filtered (not passed to command at all)
+
+ legacy_check_wrapper
+ Designed as a drop-in replacement for check_wrapper.sh . It reads $NAGIOS_HOSTNAME
+ env var and ignores check results if host component on this host is in MM.
+ When host subtitution symbol is encountered, hostname defined by $NAGIOS_HOSTNAME
+ is substituted,
+ """
+ args = sys.argv[1:] # Shift args left
+ mode, hostnames, command_line = parse_args(args)
+ output, ret_code = do_work(mode, hostnames, command_line)
+ for line in output:
+ print line
+ sys.exit(ret_code)
+
+
+if __name__ == "__main__":
+ main()
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/scripts/nagios_server_config.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/scripts/nagios_server_config.py b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/scripts/nagios_server_config.py
index 4d452c6..b0eabdc 100644
--- a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/scripts/nagios_server_config.py
+++ b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/scripts/nagios_server_config.py
@@ -65,8 +65,8 @@ def nagios_server_config():
nagios_server_check( 'check_mapred_local_dir_used.sh')
nagios_server_check( 'check_nodemanager_health.sh')
nagios_server_check( 'check_namenodes_ha.sh')
- nagios_server_check( 'check_wrapper.sh')
nagios_server_check( 'hdp_nagios_init.php')
+ nagios_server_check( 'mm_wrapper.py' )
nagios_server_check( 'check_hive_thrift_port.py' )
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-commands.cfg.j2 b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
index a81762f..ff13c0d 100644
--- a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
+++ b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
@@ -42,88 +42,88 @@
# 'check_cpu' check remote cpu load
define command {
command_name check_cpu
- command_line $USER1$/check_wrapper.sh php $USER1$/check_cpu.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_cpu.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
}
define command {
command_name check_cpu_ha
- command_line $USER1$/check_wrapper.sh php $USER1$/check_cpu_ha.php -h $ARG1$ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -u $ARG9$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py or $ARG1$ -- php $USER1$/check_cpu_ha.php -h ^^ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -u $ARG9$
}
{% endif %}
# Check data node storage full
define command {
command_name check_datanode_storage
- command_line $USER1$/check_wrapper.sh php $USER1$/check_datanode_storage.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -s $ARG8$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_datanode_storage.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -s $ARG8$
}
define command{
command_name check_hdfs_blocks
- command_line $USER1$/check_wrapper.sh php $USER1$/check_hdfs_blocks.php -h $ARG1$ -p $ARG2$ -s $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $ARG1$ -- php $USER1$/check_hdfs_blocks.php -h ^^ -p $ARG2$ -s $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
}
define command{
command_name check_hdfs_capacity
- command_line $USER1$/check_wrapper.sh php $USER1$/check_hdfs_capacity.php -h $ARG1$ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $ARG1$ -- php $USER1$/check_hdfs_capacity.php -h ^^ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
}
define command{
command_name check_aggregate
- command_line $USER1$/check_wrapper.sh php $USER1$/check_aggregate.php -f /var/nagios/status.dat -s 1 -t service -n $ARG1$ -w $ARG2$ -c $ARG3$
+ command_line php $USER1$/check_aggregate.php -f /var/nagios/status.dat -s 1 -t service -n $ARG1$ -w $ARG2$ -c $ARG3$
}
define command{
command_name check_rpcq_latency
- command_line $USER1$/check_wrapper.sh php $USER1$/check_rpcq_latency.php -h $HOSTADDRESS$ -p $ARG2$ -n $ARG1$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_rpcq_latency.php -h $HOSTADDRESS$ -p $ARG2$ -n $ARG1$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
}
define command{
command_name check_nagios
- command_line $USER1$/check_wrapper.sh $USER1$/check_nagios -e $ARG1$ -F $ARG2$ -C $ARG3$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_nagios -e $ARG1$ -F $ARG2$ -C $ARG3$
}
define command{
command_name check_webui
- command_line $USER1$/check_wrapper.sh $USER1$/check_webui.sh $ARG1$ $HOSTADDRESS$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_webui.sh $ARG1$ $HOSTADDRESS$ $ARG2$
}
define command{
command_name check_name_dir_status
- command_line $USER1$/check_wrapper.sh php $USER1$/check_name_dir_status.php -h $HOSTADDRESS$ -p $ARG1$ -e $ARG2$ -k $ARG3$ -r $ARG4$ -t $ARG5$ -s $ARG6$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_name_dir_status.php -h $HOSTADDRESS$ -p $ARG1$ -e $ARG2$ -k $ARG3$ -r $ARG4$ -t $ARG5$ -s $ARG6$
}
define command{
command_name check_oozie_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_oozie_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_oozie_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
}
define command{
command_name check_templeton_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_templeton_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_templeton_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
}
define command{
command_name check_hive_metastore_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_hive_metastore_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_hive_metastore_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
}
define command{
command_name check_hue_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_hue_status.sh
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_hue_status.sh
}
define command{
command_name check_mapred_local_dir_used_space
- command_line $USER1$/check_wrapper.sh $USER1$/check_mapred_local_dir_used.sh $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_mapred_local_dir_used.sh $ARG1$ $ARG2$
}
define command{
command_name check_namenodes_ha
- command_line $USER1$/check_wrapper.sh $USER1$/check_namenodes_ha.sh $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_namenodes_ha.sh $ARG1$ $ARG2$
}
define command{
command_name check_nodemanager_health
- command_line $USER1$/check_wrapper.sh $USER1$/check_nodemanager_health.sh $HOSTADDRESS$ $ARG1$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_nodemanager_health.sh $HOSTADDRESS$ $ARG1$
}
define command{
@@ -138,10 +138,10 @@ define command{
define command{
command_name check_tcp_wrapper
- command_line $USER1$/check_wrapper.sh $USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $HOSTADDRESS$ -- $USER1$/check_tcp -H ^^ -p $ARG1$ $ARG2$
}
define command{
command_name check_tcp_wrapper_sasl
- command_line $USER1$/check_wrapper.sh /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_hive_thrift_port.py -H $HOSTADDRESS$ -p $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_hive_thrift_port.py -H $HOSTADDRESS$ -p $ARG1$ $ARG2$
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-services.cfg.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-services.cfg.j2 b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-services.cfg.j2
index 6ce5d10..65dcb7e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-services.cfg.j2
+++ b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/hadoop-services.cfg.j2
@@ -340,7 +340,6 @@ define service {
use hadoop-service
service_description JOBTRACKER::JobTracker CPU utilization
servicegroups MAPREDUCE
-# check_command check_cpu!200%!250%
check_command check_cpu!{{ jtnode_port }}!200%!250%!{{ str(hadoop_ssl_enabled).lower() }}!{{ nagios_keytab_path }}!{{ nagios_principal_name }}!{{ kinit_path_local }}!{{ str(security_enabled).lower() }}
normal_check_interval 5
retry_check_interval 2
@@ -479,17 +478,6 @@ define service {
max_check_attempts 3
}
-{# HBASE:: MASTER Checks
-# define service {
-# hostgroup_name hbasemasters
-# use hadoop-service
-# service_description HBASEMASTER::HBase Master Web UI
-# servicegroups HBASE
-# check_command check_webui!hbase!{{ hbase_master_port }}
-# normal_check_interval 1
-# retry_check_interval 1
-# max_check_attempts 3
-# #}
{% if hostgroup_defs['hbasemasters'] %}
{% if check_cpu_on %}
define service {
@@ -497,7 +485,6 @@ define service {
use hadoop-service
service_description HBASEMASTER::HBase Master CPU utilization
servicegroups HBASE
-# check_command check_cpu!200%!250%
check_command check_cpu_ha!{{ hbase_master_hosts_in_str }}!{{ hbase_master_port }}!200%!250%!{{ str(hadoop_ssl_enabled).lower() }}!{{ nagios_keytab_path }}!{{ nagios_principal_name }}!{{ kinit_path_local }}!{{ str(security_enabled).lower() }}
normal_check_interval 5
retry_check_interval 2
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/nagios.cfg.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/nagios.cfg.j2 b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/nagios.cfg.j2
index aa37a01..8fd948d 100644
--- a/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/nagios.cfg.j2
+++ b/ambari-server/src/main/resources/stacks/HDP/1.3.2/services/NAGIOS/package/templates/nagios.cfg.j2
@@ -1283,7 +1283,7 @@ use_large_installation_tweaks=1
# Values: 1 - Enable environment variable macros (default)
# 0 - Disable environment variable macros
-# NAGIOS_* macros are required for Ambari Maintenance Mode (check_wrapper.sh)
+# NAGIOS_* macros are required for Ambari Maintenance Mode (mm_wrapper.py)
enable_environment_macros=1
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_checkpoint_time.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_checkpoint_time.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_checkpoint_time.py
index 6848e17..04e8d60 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_checkpoint_time.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_checkpoint_time.py
@@ -104,7 +104,7 @@ def get_value_from_jmx(qry, property):
exit(1)
data_dict = json.loads(data)
- return (data_dict["beans"][0][property])
+ return data_dict["beans"][0][property]
def get_available_nn_host(options, scheme):
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_wrapper.sh
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_wrapper.sh b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_wrapper.sh
deleted file mode 100644
index d350e4f..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/check_wrapper.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env bash
-#
-#
-# 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.
-#
-#
-
-function real_service() {
- desc=$NAGIOS_SERVICEGROUPNAME
- eval "$1='$desc'"
-}
-
-function real_component() {
- arrDesc=(${NAGIOS_SERVICEDESC//::/ })
-
- compName="${arrDesc[0]}"
-
- case "$compName" in
- HBASEMASTER)
- realCompName="HBASE_MASTER"
- ;;
- REGIONSERVER)
- realCompName="HBASE_REGIONSERVER"
- ;;
- JOBHISTORY)
- realCompName="MAPREDUCE2"
- ;;
- HIVE-METASTORE)
- realCompName="HIVE_METASTORE"
- ;;
- HIVE-SERVER)
- realCompName="HIVE_SERVER"
- ;;
- FLUME)
- realCompName="FLUME_HANDLER"
- ;;
- HUE)
- realCompName="HUE_SERVER"
- ;;
- WEBHCAT)
- realCompName="WEBHCAT_SERVER"
- ;;
- *)
- realCompName=$compName
- ;;
- esac
-
- eval "$1='$realCompName'"
-}
-
-real_service_var=""
-real_service real_service_var
-
-real_comp_var=""
-real_component real_comp_var
-
-
-wrapper_output=`exec "$@"`
-wrapper_result=$?
-
-if [ "$wrapper_result" == "0" ]; then
- echo "$wrapper_output"
- exit $wrapper_result
-fi
-
-if [ ! -f /var/nagios/ignore.dat ]; then
- echo "$wrapper_output"
- exit $wrapper_result
-else
- count=$(grep $NAGIOS_HOSTNAME /var/nagios/ignore.dat | grep $real_service_var | grep $real_comp_var | wc -l)
- if [ "$count" -ne "0" ]; then
- echo "$wrapper_output\nAMBARIPASSIVE=${wrapper_result}" | sed 's/^[ \t]*//g'
- exit 0
- else
- echo "$wrapper_output"
- exit $wrapper_result
- fi
-fi
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/mm_wrapper.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/mm_wrapper.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/mm_wrapper.py
new file mode 100644
index 0000000..7a622b6
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/files/mm_wrapper.py
@@ -0,0 +1,326 @@
+#!/usr/bin/env python
+
+"""
+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.
+"""
+import sys
+import subprocess
+import os
+
+N_SGN = 'NAGIOS_SERVICEGROUPNAME'
+N_SD = 'NAGIOS_SERVICEDESC'
+N_HOST = 'NAGIOS_HOSTNAME'
+
+LIST_SEPARATOR = "--"
+HOSTNAME_PLACEHOLDER = "^^"
+IGNORE_DAT_FILE = "/var/nagios/ignore.dat"
+
+# Mode constants
+OR = 0
+AND = 1
+ENV_ONLY = 2
+FILTER_MM = 3
+LEGACY_CHECK_WRAPPER = 4
+MODES = ['or', 'and', 'env_only', 'filter_mm', 'legacy_check_wrapper']
+
+
+def ignored_host_list(service, component):
+ """
+ :param service: current service
+ :param component: current component
+ :return: all hosts where specified host component is in ignored state
+ """
+ try:
+ with open(IGNORE_DAT_FILE) as f:
+ lines = f.readlines()
+ except IOError:
+ return []
+ result = []
+ if lines:
+ for l in lines:
+ tokens = l.split(' ')
+ if len(tokens) == 3 and tokens[1] == service and tokens[2].strip() == component:
+ result.append(tokens[0])
+ return result
+
+
+def get_real_service():
+ try:
+ service = os.environ[N_SGN] # e.g. 'HBASE'
+ except KeyError:
+ service = ''
+ return service
+
+
+def get_real_component():
+ try:
+ arr_desc = os.environ[N_SD] # e.g. 'HBASE::Percent RegionServers live'
+ SEPARATOR = "::"
+ comp_name = arr_desc.replace(SEPARATOR, ' ').split(' ')[0]
+ except KeyError:
+ comp_name = ''
+ mapping = {
+ 'HBASEMASTER': 'HBASE_MASTER',
+ 'REGIONSERVER': 'HBASE_REGIONSERVER',
+ 'JOBHISTORY': 'MAPREDUCE2',
+ 'HIVE-METASTORE': 'HIVE_METASTORE',
+ 'HIVE-SERVER': 'HIVE_SERVER',
+ 'FLUME': 'FLUME_HANDLER',
+ 'HUE': 'HUE_SERVER',
+ 'WEBHCAT': 'WEBHCAT_SERVER',
+ }
+ if comp_name in mapping:
+ comp_name = mapping.get(comp_name)
+ return comp_name
+
+
+def check_output(*popenargs, **kwargs):
+ """
+ Imitate subprocess.check_output() for python 2.6
+ """
+ process = subprocess.Popen(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ *popenargs, **kwargs)
+ output, unused_err = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ err = subprocess.CalledProcessError(retcode, cmd)
+ # Monkey-patching for python 2.6
+ err.output = output
+ raise err
+ return output
+
+
+def print_usage():
+ """
+ Prints usage and exits with a non-zero exit code
+ """
+ print "Usage: mm_wrapper.py MODE HOST1 HOST2 .. HOSTN %s command arg1 arg2 .. argN" % LIST_SEPARATOR
+ print "MODE is one of the following: or, and, env_only, filter_mm, legacy_check_wrapper"
+ print "%s is a separator between list of hostnames and command with args" % LIST_SEPARATOR
+ print "%s is used as a hostname placeholder at command args" % HOSTNAME_PLACEHOLDER
+ print "Also script provides $MM_HOSTS shell variable to commands"
+ print "NOTE: Script makes use of Nagios-populated env vars %s and %s" % (N_SGN, N_SD)
+ print "For more info, please see docstrings at %s" % os.path.realpath(__file__)
+ sys.exit(1)
+
+
+def parse_args(args):
+ if not args or not LIST_SEPARATOR in args or args[0] not in MODES:
+ print_usage()
+ else:
+ mode = MODES.index(args[0]) # identify operation mode
+ args = args[1:] # Shift args left
+ hostnames = []
+ command_line = []
+ # Parse command line args
+ passed_separator = False # True if met LIST_SEPARATOR
+ for arg in args:
+ if not passed_separator:
+ if arg != LIST_SEPARATOR:
+ hostnames.append(arg)
+ else:
+ passed_separator = True
+ else:
+ if arg != LIST_SEPARATOR:
+ command_line.append(arg)
+ else: # Something definitely goes wrong
+ print "Could not parse arguments: " \
+ "There is more than one %s argument." % LIST_SEPARATOR
+ print_usage()
+
+ if not command_line:
+ print "No command provided."
+ print_usage()
+ return mode, hostnames, command_line
+
+
+def do_work(mode, hostnames, command_line):
+ # Execute commands
+ ignored_hosts = ignored_host_list(get_real_service(), get_real_component())
+ empty_check_result = {
+ 'message': 'No checks have been run (no hostnames provided)',
+ 'retcode': -1,
+ 'real_retcode': None
+ }
+ custom_env = os.environ.copy()
+ if ignored_hosts:
+ custom_env['MM_HOSTS'] = \
+ reduce(lambda a, b: "%s %s" % (a, b), ignored_hosts)
+ if mode == OR:
+ check_result = work_in_or_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result)
+ elif mode == AND:
+ check_result = work_in_and_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result)
+ elif mode == ENV_ONLY:
+ check_result = work_in_env_only_mode(hostnames, command_line, custom_env)
+ elif mode == FILTER_MM:
+ check_result = work_in_filter_mm_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result)
+ else: # mode == LEGACY_CHECK_WRAPPER:
+ check_result = work_in_legacy_check_wrapper_mode(ignored_hosts, command_line, custom_env)
+ # Build the final output
+ final_output = []
+ output = check_result.get('message')
+ if output is not None:
+ for string in output.splitlines():
+ final_output.append(string.strip())
+ real_retcode = check_result.get('real_retcode')
+ if real_retcode:
+ # This string is used at check_aggregate.php when aggregating alerts
+ final_output.append("AMBARIPASSIVE=%s" % real_retcode)
+ return final_output, check_result.get('retcode')
+
+
+def work_in_or_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result):
+ check_result = empty_check_result
+ for hostname in hostnames:
+ concrete_command_line = map( # Substitute hostname where needed
+ lambda x: hostname if x == HOSTNAME_PLACEHOLDER else x,
+ command_line)
+ try:
+ returncode = 0
+ real_retcode = None
+ message = check_output(concrete_command_line, env=custom_env)
+ except subprocess.CalledProcessError, e:
+ if hostname not in ignored_hosts:
+ returncode = e.returncode
+ else: # Host is in MM
+ real_retcode = e.returncode
+ message = e.output
+ really_positive_result = hostname not in ignored_hosts and returncode == 0
+ if check_result.get('retcode') <= returncode or really_positive_result:
+ check_result = {
+ 'message': message,
+ 'retcode': returncode,
+ 'real_retcode': real_retcode # Real (not suppressed) program retcode
+ }
+ if really_positive_result:
+ break # Exit on first real success
+ return check_result
+
+
+def work_in_and_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result):
+ check_result = empty_check_result
+ for hostname in hostnames:
+ concrete_command_line = map( # Substitute hostname where needed
+ lambda x: hostname if x == HOSTNAME_PLACEHOLDER else x,
+ command_line)
+ try:
+ returncode = 0
+ real_retcode = None
+ message = check_output(concrete_command_line, env=custom_env)
+ except subprocess.CalledProcessError, e:
+ if hostname not in ignored_hosts:
+ returncode = e.returncode
+ else:
+ real_retcode = e.returncode
+ message = e.output
+ if check_result.get('retcode') <= returncode:
+ check_result = {
+ 'message': message,
+ 'retcode': returncode,
+ 'real_retcode': real_retcode # Real (not suppressed) program retcode
+ }
+ return check_result
+
+
+def work_in_env_only_mode(hostnames, command_line, custom_env):
+ concrete_command_line = []
+ for item in command_line:
+ if item == HOSTNAME_PLACEHOLDER:
+ concrete_command_line.extend(hostnames)
+ else:
+ concrete_command_line.append(item)
+ try:
+ returncode = 0
+ message = check_output(concrete_command_line, env=custom_env)
+ except subprocess.CalledProcessError, e:
+ returncode = e.returncode
+ message = e.output
+ check_result = {
+ 'message': message,
+ 'retcode': returncode,
+ 'real_retcode': None # Real (not suppressed) program retcode
+ }
+ return check_result
+
+
+def work_in_filter_mm_mode(hostnames, ignored_hosts, command_line, custom_env, empty_check_result):
+ not_mm_hosts = [hostname for hostname in hostnames if hostname not in ignored_hosts]
+ if not not_mm_hosts: # All hosts have been filtered
+ return empty_check_result
+ else:
+ return work_in_env_only_mode(not_mm_hosts, command_line, custom_env)
+
+
+def work_in_legacy_check_wrapper_mode(ignored_hosts, command_line, custom_env):
+ host = os.environ[N_HOST]
+ result = work_in_env_only_mode([host], command_line, custom_env)
+ real_retcode = result['retcode']
+ if host in ignored_hosts and real_retcode != 0: # Ignore fail
+ result['retcode'] = 0
+ result['real_retcode'] = real_retcode
+ return result
+
+
+def main():
+ """
+ This script allows to run nagios service check commands for host components
+ located at different hosts.
+ Also script passes to every command a $MM_HOSTS shell variable with a list of
+ hosts that are in MM
+
+ or mode: return 0 exit code if at least one service check succeeds.
+ Command exits on a first success.
+ Failures for host components that are in MM are suppressed (return code
+ is set to 0).
+ If command fails for all provided hostnames, script returns alert with the
+ greatest exit code value.
+
+ and mode:
+ Perform checks of all host components (effectively ignoring negative results
+ for MM components). If service check is successful for all hosts, script
+ also returns zero exit code. Otherwise alert with the greatest exit code is
+ returned.
+
+ env_only mode:
+ Pass list of all hosts to command and run it once. The only role of
+ mm_wrapper script in this mode is to provide properly initialized
+ $MM_HOSTS env variable to command being run. All duties of ignoring failures
+ of MM host components are delegated to a command being run.
+
+ filter_mm
+ Similar to env_only mode. The only difference is that hostnames for
+ host components that are in MM are filtered (not passed to command at all)
+
+ legacy_check_wrapper
+ Designed as a drop-in replacement for check_wrapper.sh . It reads $NAGIOS_HOSTNAME
+ env var and ignores check results if host component on this host is in MM.
+ When host subtitution symbol is encountered, hostname defined by $NAGIOS_HOSTNAME
+ is substituted,
+ """
+ args = sys.argv[1:] # Shift args left
+ mode, hostnames, command_line = parse_args(args)
+ output, ret_code = do_work(mode, hostnames, command_line)
+ for line in output:
+ print line
+ sys.exit(ret_code)
+
+
+if __name__ == "__main__":
+ main()
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/scripts/nagios_server_config.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/scripts/nagios_server_config.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/scripts/nagios_server_config.py
index 4efce9b..883442c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/scripts/nagios_server_config.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/scripts/nagios_server_config.py
@@ -67,11 +67,11 @@ def nagios_server_config():
nagios_server_check( 'check_mapred_local_dir_used.sh')
nagios_server_check( 'check_nodemanager_health.sh')
nagios_server_check( 'check_namenodes_ha.sh')
- nagios_server_check( 'check_wrapper.sh')
nagios_server_check( 'hdp_nagios_init.php')
nagios_server_check( 'check_checkpoint_time.py' )
nagios_server_check( 'sys_logger.py' )
nagios_server_check( 'check_ambari_alerts.py' )
+ nagios_server_check( 'mm_wrapper.py' )
nagios_server_check( 'check_hive_thrift_port.py' )
def nagios_server_configfile(
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-commands.cfg.j2 b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
index 9a6f7a4..c1a792c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-commands.cfg.j2
@@ -42,97 +42,97 @@
# 'check_cpu' check remote cpu load
define command {
command_name check_cpu
- command_line $USER1$/check_wrapper.sh php $USER1$/check_cpu.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_cpu.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
}
define command {
command_name check_cpu_ha
- command_line $USER1$/check_wrapper.sh php $USER1$/check_cpu_ha.php -h $ARG1$ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -u $ARG9$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py or $ARG1$ -- php $USER1$/check_cpu_ha.php -h ^^ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -u $ARG9$
}
{% endif %}
# Check data node storage full
define command {
command_name check_datanode_storage
- command_line $USER1$/check_wrapper.sh php $USER1$/check_datanode_storage.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -s $ARG8$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_datanode_storage.php -h $HOSTADDRESS$ -p $ARG1$ -w $ARG2$ -c $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -s $ARG8$
}
define command{
command_name check_hdfs_blocks
- command_line $USER1$/check_wrapper.sh php $USER1$/check_hdfs_blocks.php -h $ARG1$ -p $ARG2$ -s $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $ARG1$ -- php $USER1$/check_hdfs_blocks.php -h ^^ -p $ARG2$ -s $ARG3$ -e $ARG4$ -k $ARG5$ -r $ARG6$ -t $ARG7$ -u $ARG8$
}
define command{
command_name check_hdfs_capacity
- command_line $USER1$/check_wrapper.sh php $USER1$/check_hdfs_capacity.php -h $ARG1$ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $ARG1$ -- php $USER1$/check_hdfs_capacity.php -h ^^ -p $ARG2$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
}
define command{
command_name check_aggregate
- command_line $USER1$/check_wrapper.sh php $USER1$/check_aggregate.php -f /var/nagios/status.dat -s 1 -t service -n $ARG1$ -w $ARG2$ -c $ARG3$
+ command_line php $USER1$/check_aggregate.php -f /var/nagios/status.dat -s 1 -t service -n $ARG1$ -w $ARG2$ -c $ARG3$
}
define command{
command_name check_rpcq_latency
- command_line $USER1$/check_wrapper.sh php $USER1$/check_rpcq_latency.php -h $HOSTADDRESS$ -p $ARG2$ -n $ARG1$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_rpcq_latency.php -h $HOSTADDRESS$ -p $ARG2$ -n $ARG1$ -w $ARG3$ -c $ARG4$ -e $ARG5$ -k $ARG6$ -r $ARG7$ -t $ARG8$ -s $ARG9$
}
define command{
command_name check_rpcq_latency_ha
- command_line $USER1$/check_wrapper.sh php $USER1$/check_rpcq_latency_ha.php -h $ARG1$ -p $ARG3$ -n $ARG2$ -w $ARG4$ -c $ARG5$ -e $ARG6$ -k $ARG7$ -r $ARG8$ -t $ARG9$ -s $ARG10$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py or $ARG1$ -- php $USER1$/check_rpcq_latency_ha.php -h ^^ -p $ARG3$ -n $ARG2$ -w $ARG4$ -c $ARG5$ -e $ARG6$ -k $ARG7$ -r $ARG8$ -t $ARG9$ -s $ARG10$
}
define command{
command_name check_nagios
- command_line $USER1$/check_wrapper.sh $USER1$/check_nagios -e $ARG1$ -F $ARG2$ -C $ARG3$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_nagios -e $ARG1$ -F $ARG2$ -C $ARG3$
}
define command{
command_name check_webui
- command_line $USER1$/check_wrapper.sh $USER1$/check_webui.sh $ARG1$ $HOSTADDRESS$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_webui.sh $ARG1$ $HOSTADDRESS$ $ARG2$
}
define command{
command_name check_webui_ha
- command_line $USER1$/check_wrapper.sh $USER1$/check_webui_ha.sh $ARG1$ $ARG2$ $ARG3$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $ARG2$ -- $USER1$/check_webui_ha.sh $ARG1$ ^^ $ARG3$
}
define command{
command_name check_name_dir_status
- command_line $USER1$/check_wrapper.sh php $USER1$/check_name_dir_status.php -h $HOSTADDRESS$ -p $ARG1$ -e $ARG2$ -k $ARG3$ -r $ARG4$ -t $ARG5$ -s $ARG6$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- php $USER1$/check_name_dir_status.php -h $HOSTADDRESS$ -p $ARG1$ -e $ARG2$ -k $ARG3$ -r $ARG4$ -t $ARG5$ -s $ARG6$
}
define command{
command_name check_oozie_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_oozie_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_oozie_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
}
define command{
command_name check_templeton_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_templeton_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_templeton_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
}
define command{
command_name check_hive_metastore_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_hive_metastore_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_hive_metastore_status.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$
}
define command{
command_name check_hue_status
- command_line $USER1$/check_wrapper.sh $USER1$/check_hue_status.sh
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_hue_status.sh
}
define command{
command_name check_mapred_local_dir_used_space
- command_line $USER1$/check_wrapper.sh $USER1$/check_mapred_local_dir_used.sh $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_mapred_local_dir_used.sh $ARG1$ $ARG2$
}
define command{
command_name check_namenodes_ha
- command_line $USER1$/check_wrapper.sh $USER1$/check_namenodes_ha.sh $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_namenodes_ha.sh $ARG1$ $ARG2$
}
define command{
command_name check_nodemanager_health
- command_line $USER1$/check_wrapper.sh $USER1$/check_nodemanager_health.sh $HOSTADDRESS$ $ARG1$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- $USER1$/check_nodemanager_health.sh $HOSTADDRESS$ $ARG1$
}
define command{
@@ -147,20 +147,20 @@ define command{
define command{
command_name check_tcp_wrapper
- command_line $USER1$/check_wrapper.sh $USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $HOSTADDRESS$ -- $USER1$/check_tcp -H ^^ -p $ARG1$ $ARG2$
}
define command{
command_name check_checkpoint_time
- command_line $USER1$/check_wrapper.sh /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_checkpoint_time.py -H "$ARG1$" -p $ARG2$ -w $ARG3$ -c $ARG4$ -t $ARG5$ -x $ARG6$ -s $ARG7$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py or $ARG1$ -- /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_checkpoint_time.py -H ^^ -p $ARG2$ -w $ARG3$ -c $ARG4$ -t $ARG5$ -x $ARG6$ -s $ARG7$
}
define command{
command_name check_tcp_wrapper_sasl
- command_line $USER1$/check_wrapper.sh /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_hive_thrift_port.py -H $HOSTADDRESS$ -p $ARG1$ $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py and $HOSTADDRESS$ -- /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_hive_thrift_port.py -H ^^ -p $ARG1$ $ARG2$
}
define command{
command_name check_ambari
- command_line $USER1$/check_wrapper.sh /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_ambari_alerts.py -H $HOSTADDRESS$ -f $ARG1$ -n $ARG2$
+ command_line /var/lib/ambari-agent/ambari-python-wrap $USER1$/mm_wrapper.py legacy_check_wrapper -- /var/lib/ambari-agent/ambari-python-wrap $USER1$/check_ambari_alerts.py -H $HOSTADDRESS$ -f $ARG1$ -n $ARG2$
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-services.cfg.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-services.cfg.j2 b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-services.cfg.j2
index 1ed55d1..f94a6ca 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-services.cfg.j2
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/hadoop-services.cfg.j2
@@ -344,7 +344,6 @@ define service {
use hadoop-service
service_description NAMENODE::NameNode host CPU utilization on {{ namenode_hostname }}
servicegroups HDFS
-# check_command check_cpu!200%!250%
check_command check_cpu!{{ namenode_port }}!200%!250%!{{ str(hdfs_ssl_enabled).lower() }}!{{ nagios_keytab_path }}!{{ nagios_principal_name }}!{{ kinit_path_local }}!{{ str(security_enabled).lower() }}
normal_check_interval 5
retry_check_interval 2
@@ -441,7 +440,6 @@ define service {
use hadoop-service
service_description RESOURCEMANAGER::ResourceManager CPU utilization
servicegroups YARN
-# check_command check_cpu!200%!250%
check_command check_cpu_ha!{{ rm_hosts_in_str }}!{{ rm_port }}!200%!250%!{{ str(yarn_ssl_enabled).lower() }}!{{ nagios_keytab_path }}!{{ nagios_principal_name }}!{{ kinit_path_local }}!{{ str(security_enabled).lower() }}
normal_check_interval 5
retry_check_interval 2
@@ -528,7 +526,6 @@ define service {
use hadoop-service
service_description JOBHISTORY::HistoryServer CPU utilization
servicegroups MAPREDUCE
-# check_command check_cpu!200%!250%
check_command check_cpu!{{ hs_port }}!200%!250%!{{ str(mapreduce_ssl_enabled).lower() }}!{{ nagios_keytab_path }}!{{ nagios_principal_name }}!{{ kinit_path_local }}!{{ str(security_enabled).lower() }}
normal_check_interval 5
retry_check_interval 2
@@ -640,17 +637,6 @@ define service {
max_check_attempts 3
}
-{# HBASE:: MASTER Checks
-# define service {
-# hostgroup_name hbasemasters
-# use hadoop-service
-# service_description HBASEMASTER::HBase Master Web UI
-# servicegroups HBASE
-# check_command check_webui!hbase!{{ hbase_master_port }}
-# normal_check_interval 1
-# retry_check_interval 1
-# max_check_attempts 3
-# #}
{% if hostgroup_defs['hbasemasters'] %}
{% if check_cpu_on %}
define service {
@@ -658,7 +644,6 @@ define service {
use hadoop-service
service_description HBASEMASTER::HBase Master CPU utilization
servicegroups HBASE
-# check_command check_cpu!200%!250%
check_command check_cpu_ha!{{ hbase_master_hosts_in_str }}!{{ hbase_master_port }}!200%!250%!false!{{ nagios_keytab_path }}!{{ nagios_principal_name }}!{{ kinit_path_local }}!{{ str(security_enabled).lower() }}
normal_check_interval 5
retry_check_interval 2
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/nagios.cfg.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/nagios.cfg.j2 b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/nagios.cfg.j2
index d51471b..bcff8ac 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/nagios.cfg.j2
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/nagios.cfg.j2
@@ -1280,7 +1280,7 @@ use_large_installation_tweaks=1
# Values: 1 - Enable environment variable macros (default)
# 0 - Disable environment variable macros
-# NAGIOS_* macros are required for Ambari Maintenance Mode (check_wrapper.sh)
+# NAGIOS_* macros are required for Ambari Maintenance Mode (mm_wrapper.py)
enable_environment_macros=1
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_mm_wrapper.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_mm_wrapper.py b/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_mm_wrapper.py
new file mode 100644
index 0000000..8bb139f
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_mm_wrapper.py
@@ -0,0 +1,459 @@
+#!/usr/bin/env python
+
+'''
+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.
+'''
+import StringIO
+
+import os, sys
+import pprint
+import subprocess
+from unittest import TestCase
+from mock.mock import Mock, MagicMock, patch
+import mm_wrapper
+
+class TestOrWrapper(TestCase):
+
+ dummy_ignore_file = """
+vm-4.vm HIVE HIVE_METASTORE
+vm-5.vm GANGLIA GANGLIA_MONITOR
+vm-4.vm YARN NODEMANAGER
+vm-3.vm YARN NODEMANAGER
+vm-3.vm HBASE HBASE_REGIONSERVER
+vm-4.vm HBASE HBASE_REGIONSERVER
+vm-4.vm STORM STORM_REST_API
+vm-4.vm HDFS DATANODE
+vm-4.vm STORM SUPERVISOR
+vm-4.vm STORM NIMBUS
+vm-4.vm STORM STORM_UI_SERVER
+vm-3.vm STORM SUPERVISOR
+vm-4.vm HDFS SECONDARY_NAMENODE
+vm-3.vm FLUME FLUME_HANDLER
+vm-4.vm GANGLIA GANGLIA_SERVER
+vm-4.vm HIVE HIVE_SERVER
+vm-4.vm ZOOKEEPER ZOOKEEPER_SERVER
+vm-4.vm WEBHCAT WEBHCAT_SERVER
+vm-3.vm HBASE HBASE_MASTER
+vm-4.vm GANGLIA GANGLIA_MONITOR
+vm-3.vm GANGLIA GANGLIA_MONITOR
+vm-3.vm HDFS NAMENODE
+vm-4.vm HIVE MYSQL_SERVER
+vm-4.vm YARN APP_TIMELINE_SERVER
+vm-4.vm FALCON FALCON_SERVER
+vm-3.vm HDFS DATANODE
+vm-4.vm YARN RESOURCEMANAGER
+vm-4.vm OOZIE OOZIE_SERVER
+vm-4.vm MAPREDUCE2 HISTORYSERVER
+vm-4.vm STORM DRPC_SERVER
+vm-4.vm FLUME FLUME_HANDLER
+vm-3.vm ZOOKEEPER ZOOKEEPER_SERVER
+"""
+
+ default_empty_check_result = {
+ 'message': 'No checks have been run (no hostnames provided)',
+ 'retcode': -1,
+ 'real_retcode': None
+ }
+
+
+ @patch("__builtin__.open")
+ def test_ignored_host_list(self, open_mock):
+ # Check with empty file content
+ open_mock.return_value.__enter__.return_value.readlines.return_value = []
+ lst = mm_wrapper.ignored_host_list('STORM', 'SUPERVISOR')
+ self.assertEqual(pprint.pformat(lst), '[]')
+ # Check with dummy content
+ open_mock.return_value.__enter__.return_value.readlines.return_value = self.dummy_ignore_file.splitlines()
+ lst = mm_wrapper.ignored_host_list('STORM', 'SUPERVISOR')
+ self.assertEqual(pprint.pformat(lst), "['vm-4.vm', 'vm-3.vm']")
+ # Check if service name/comp name are not defined
+ open_mock.return_value.__enter__.return_value.readlines.return_value = self.dummy_ignore_file.splitlines()
+ lst = mm_wrapper.ignored_host_list('', '')
+ self.assertEqual(pprint.pformat(lst), "[]")
+
+
+ @patch("sys.exit")
+ def test_print_usage(self, exit_mock):
+ mm_wrapper.print_usage()
+ self.assertTrue(exit_mock.called)
+ self.assertEqual(exit_mock.call_args_list[0][0][0], 1)
+
+
+ def test_get_real_component(self):
+ with patch.dict(os.environ, {'NAGIOS_SERVICEDESC': 'SUPERVISOR::Supervisors process'}, clear=True):
+ component = mm_wrapper.get_real_component()
+ self.assertEqual(component, 'SUPERVISOR')
+ with patch.dict(os.environ, {'NAGIOS_SERVICEDESC': 'JOBHISTORY::HistoryServer process'}, clear=True):
+ component = mm_wrapper.get_real_component()
+ self.assertEqual(component, 'MAPREDUCE2')
+
+
+ @patch("mm_wrapper.print_usage")
+ def test_parse_args(self, print_usage_mock):
+ args = ['or', 'h1', 'h2', '--', 'prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ mode, hostnames, command_line = mm_wrapper.parse_args(args)
+ self.assertEquals(mode, mm_wrapper.OR)
+ self.assertEquals(hostnames, ['h1', 'h2'])
+ self.assertEquals(command_line, ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt'])
+
+ args = ['and', 'h1', 'h2', '--', 'prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ mode, hostnames, command_line = mm_wrapper.parse_args(args)
+ self.assertEquals(mode, mm_wrapper.AND)
+ self.assertEquals(hostnames, ['h1', 'h2'])
+ self.assertEquals(command_line, ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt'])
+
+ args = ['env_only', 'h1', 'h2', '--', 'prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ mode, hostnames, command_line = mm_wrapper.parse_args(args)
+ self.assertEquals(mode, mm_wrapper.ENV_ONLY)
+ self.assertEquals(hostnames, ['h1', 'h2'])
+ self.assertEquals(command_line, ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt'])
+
+ # Check wrong usage
+ args = []
+ mm_wrapper.parse_args(args)
+ self.assertTrue(print_usage_mock.called)
+
+
+ @patch("mm_wrapper.ignored_host_list")
+ @patch("mm_wrapper.work_in_or_mode")
+ @patch("mm_wrapper.work_in_and_mode")
+ @patch("mm_wrapper.work_in_env_only_mode")
+ @patch("mm_wrapper.work_in_filter_mm_mode")
+ @patch("mm_wrapper.work_in_legacy_check_wrapper_mode")
+ def test_do_work(self, work_in_legacy_check_wrapper_mode, work_in_filter_mm_mode_mock,
+ work_in_env_only_mode_mock, work_in_and_mode_mock,
+ work_in_or_mode_mock,
+ ignored_host_list_mock):
+ hostnames = ['h1', 'h2', 'h3', 'h4']
+ ignored_host_list_mock.return_value = ['h2', 'h3']
+ command_line = ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ work_in_or_mode_mock.return_value = {
+ 'message': "or_mode mode result",
+ 'retcode': 0,
+ 'real_retcode': None
+ }
+ work_in_and_mode_mock.return_value = {
+ 'message': "and_mode mode result",
+ 'retcode': 0,
+ 'real_retcode': None
+ }
+ work_in_env_only_mode_mock.return_value = {
+ 'message': "env_only mode result",
+ 'retcode': 0,
+ 'real_retcode': None
+ }
+ work_in_filter_mm_mode_mock.return_value = {
+ 'message': "filter_mm mode result",
+ 'retcode': 0,
+ 'real_retcode': None
+ }
+ work_in_legacy_check_wrapper_mode.return_value = {
+ 'message': "legacy_check_wrapper mode result",
+ 'retcode': 0,
+ 'real_retcode': None
+ }
+ result = mm_wrapper.do_work(mm_wrapper.OR, hostnames, command_line)
+ self.assertEquals(str(result), "(['or_mode mode result'], 0)")
+
+ result = mm_wrapper.do_work(mm_wrapper.AND, hostnames, command_line)
+ self.assertEquals(str(result), "(['and_mode mode result'], 0)")
+
+ result = mm_wrapper.do_work(mm_wrapper.ENV_ONLY, hostnames, command_line)
+ self.assertEquals(str(result), "(['env_only mode result'], 0)")
+
+ result = mm_wrapper.do_work(mm_wrapper.FILTER_MM, hostnames, command_line)
+ self.assertEquals(str(result), "(['filter_mm mode result'], 0)")
+
+ result = mm_wrapper.do_work(mm_wrapper.LEGACY_CHECK_WRAPPER, hostnames, command_line)
+ self.assertEquals(str(result), "(['legacy_check_wrapper mode result'], 0)")
+
+ # Check behaviour when real_retcode is defined
+ work_in_or_mode_mock.return_value = {
+ 'message': "or_mode mode result",
+ 'retcode': 0,
+ 'real_retcode': 1
+ }
+ result = mm_wrapper.do_work(mm_wrapper.OR, hostnames, command_line)
+ self.assertEquals(str(result), "(['or_mode mode result', 'AMBARIPASSIVE=1'], 0)")
+
+
+ @patch("mm_wrapper.check_output")
+ def test_work_in_or_mode(self, check_output_mock):
+ hostnames = ['h1', 'h2', 'h3', 'h4']
+ ignored_hosts = ['h2', 'h3']
+ command_line = ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ custom_env = {'MM_HOSTS': ignored_hosts}
+
+ # Normal usage
+ check_output_mock.return_value = 'Dummy message'
+ result = mm_wrapper.work_in_or_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(str(result),
+ "{'message': 'Dummy message', 'real_retcode': None, 'retcode': 0}")
+ self.assertEquals(check_output_mock.call_count, 1) # Exited on first success
+ self.assertEquals(check_output_mock.call_args[1]['env']['MM_HOSTS'], ignored_hosts)
+ for check_tupple in zip(check_output_mock.call_args_list, hostnames):
+ self.assertEquals(check_tupple[0][0][0], ['prog', '-h', check_tupple[1], '-opt', 'yet', 'another', 'opt'])
+
+ check_output_mock.reset_mock()
+
+ # Failed all checks
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ subprocess.CalledProcessError(3, 'dummy cmd', output='dummy output2'),
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output3'),
+ subprocess.CalledProcessError(2, 'dummy cmd', output='dummy output4'),
+ ]
+ result = mm_wrapper.work_in_or_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 4)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output4', 'real_retcode': None, 'retcode': 2}")
+
+ check_output_mock.reset_mock()
+
+ # Failed all but MM host component checks
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ subprocess.CalledProcessError(0, 'dummy cmd', output='dummy output2'),
+ subprocess.CalledProcessError(2, 'dummy cmd', output='dummy output3'),
+ subprocess.CalledProcessError(3, 'dummy cmd', output='dummy output4'),
+ ]
+ result = mm_wrapper.work_in_or_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 4)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output4', 'real_retcode': None, 'retcode': 3}")
+
+ check_output_mock.reset_mock()
+
+ # Components check only for one check is successful
+ ignored_hosts = []
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ subprocess.CalledProcessError(0, 'dummy cmd', output='dummy output2'),
+ subprocess.CalledProcessError(2, 'dummy cmd', output='dummy output3'),
+ subprocess.CalledProcessError(3, 'dummy cmd', output='dummy output4'),
+ ]
+ result = mm_wrapper.work_in_or_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 2)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output2', 'real_retcode': None, 'retcode': 0}")
+
+
+ @patch("mm_wrapper.check_output")
+ def test_work_in_and_mode(self, check_output_mock):
+ hostnames = ['h1', 'h2', 'h3', 'h4']
+ ignored_hosts = ['h2', 'h3']
+ command_line = ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ custom_env = {'MM_HOSTS': ignored_hosts}
+
+ # Normal usage
+ check_output_mock.return_value = 'Dummy message'
+ result = mm_wrapper.work_in_and_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(str(result),
+ "{'message': 'Dummy message', 'real_retcode': None, 'retcode': 0}")
+ self.assertEquals(check_output_mock.call_count, 4)
+ self.assertEquals(check_output_mock.call_args[1]['env']['MM_HOSTS'], ignored_hosts)
+ for check_tupple in zip(check_output_mock.call_args_list, hostnames):
+ self.assertEquals(check_tupple[0][0][0], ['prog', '-h', check_tupple[1], '-opt', 'yet', 'another', 'opt'])
+
+ check_output_mock.reset_mock()
+
+ # Failed all checks
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ subprocess.CalledProcessError(3, 'dummy cmd', output='dummy output2'),
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output3'),
+ subprocess.CalledProcessError(2, 'dummy cmd', output='dummy output4'),
+ ]
+ result = mm_wrapper.work_in_and_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 4)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output4', 'real_retcode': None, 'retcode': 2}")
+
+ check_output_mock.reset_mock()
+
+ # Failed all but MM host component checks
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ subprocess.CalledProcessError(0, 'dummy cmd', output='dummy output2'),
+ subprocess.CalledProcessError(2, 'dummy cmd', output='dummy output3'),
+ subprocess.CalledProcessError(3, 'dummy cmd', output='dummy output4'),
+ ]
+ result = mm_wrapper.work_in_and_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 4)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output4', 'real_retcode': None, 'retcode': 3}")
+
+ check_output_mock.reset_mock()
+
+ # Components check only for one check is successful
+ ignored_hosts = []
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ subprocess.CalledProcessError(0, 'dummy cmd', output='dummy output2'),
+ subprocess.CalledProcessError(2, 'dummy cmd', output='dummy output3'),
+ subprocess.CalledProcessError(3, 'dummy cmd', output='dummy output4'),
+ ]
+ result = mm_wrapper.work_in_and_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 4)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output4', 'real_retcode': None, 'retcode': 3}")
+
+
+ @patch("mm_wrapper.check_output")
+ def test_work_in_env_only_mode(self, check_output_mock):
+ hostnames = ['h1', 'h2', 'h3', 'h4']
+ ignored_hosts = ['h2', 'h3']
+ command_line = ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ custom_env = {'MM_HOSTS' : ignored_hosts}
+
+ # Normal usage
+ check_output_mock.return_value = 'Dummy message'
+ result = mm_wrapper.work_in_env_only_mode(hostnames, command_line, custom_env)
+ self.assertEquals(str(result),
+ "{'message': 'Dummy message', 'real_retcode': None, 'retcode': 0}")
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(check_output_mock.call_args[1]['env']['MM_HOSTS'], ignored_hosts)
+ self.assertEquals(check_output_mock.call_args[0][0],
+ ['prog', '-h', 'h1', 'h2', 'h3', 'h4', '-opt', 'yet', 'another', 'opt'])
+
+ check_output_mock.reset_mock()
+
+ # Failed all checks
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ ]
+ result = mm_wrapper.work_in_env_only_mode(hostnames, command_line, custom_env)
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output1', 'real_retcode': None, 'retcode': 1}")
+
+ check_output_mock.reset_mock()
+
+
+ @patch("mm_wrapper.check_output")
+ def test_work_in_filter_mm_mode(self, check_output_mock):
+ hostnames = ['h1', 'h2', 'h3', 'h4']
+ ignored_hosts = ['h2', 'h3']
+ command_line = ['prog', '-h', '^^', '-opt', 'yet', 'another', 'opt']
+ custom_env = {'MM_HOSTS' : ignored_hosts}
+
+ # Normal usage
+ check_output_mock.return_value = 'Dummy message'
+ result = mm_wrapper.work_in_filter_mm_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(str(result),
+ "{'message': 'Dummy message', 'real_retcode': None, 'retcode': 0}")
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(check_output_mock.call_args[1]['env']['MM_HOSTS'], ignored_hosts)
+ self.assertEquals(check_output_mock.call_args[0][0],
+ ['prog', '-h', 'h1', 'h4', '-opt', 'yet', 'another', 'opt'])
+
+ check_output_mock.reset_mock()
+
+ # Failed all checks
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ ]
+ result = mm_wrapper.work_in_filter_mm_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output1', 'real_retcode': None, 'retcode': 1}")
+
+ check_output_mock.reset_mock()
+
+ # All host components are in MM
+ ignored_hosts = hostnames
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ ]
+ result = mm_wrapper.work_in_filter_mm_mode(hostnames, ignored_hosts, command_line,
+ custom_env,
+ self.default_empty_check_result)
+ self.assertEquals(check_output_mock.call_count, 0)
+ self.assertEquals(str(result),
+ "{'message': 'No checks have been run (no hostnames provided)', "
+ "'real_retcode': None, 'retcode': -1}")
+
+ check_output_mock.reset_mock()
+
+
+ @patch("mm_wrapper.check_output")
+ @patch.dict(os.environ, {'NAGIOS_HOSTNAME': 'h2'}, clear=True)
+ def test_work_in_legacy_check_wrapper_mode(self, check_output_mock):
+ command_line = ['prog', '-opt', 'yet', 'another', 'opt']
+ ignored_hosts = []
+ custom_env = {'MM_HOSTS': ignored_hosts}
+
+ # Normal usage
+ ignored_hosts = []
+ check_output_mock.return_value = 'Dummy message'
+ result = mm_wrapper.work_in_legacy_check_wrapper_mode(ignored_hosts, command_line,
+ custom_env)
+ self.assertEquals(str(result),
+ "{'message': 'Dummy message', 'real_retcode': None, 'retcode': 0}")
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(check_output_mock.call_args[1]['env']['MM_HOSTS'], ignored_hosts)
+ self.assertEquals(check_output_mock.call_args[0][0],
+ ['prog', '-opt', 'yet', 'another', 'opt'])
+
+ check_output_mock.reset_mock()
+
+ # Failed check on host that is not in MM state
+ ignored_hosts = ['h3']
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ ]
+ result = mm_wrapper.work_in_legacy_check_wrapper_mode(ignored_hosts, command_line,
+ custom_env)
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output1', 'real_retcode': None, 'retcode': 1}")
+
+ check_output_mock.reset_mock()
+
+ # Failed check on host that is in MM state
+ ignored_hosts = ['h2']
+ check_output_mock.side_effect = [
+ subprocess.CalledProcessError(1, 'dummy cmd', output='dummy output1'),
+ ]
+ result = mm_wrapper.work_in_legacy_check_wrapper_mode(ignored_hosts, command_line,
+ custom_env)
+ self.assertEquals(check_output_mock.call_count, 1)
+ self.assertEquals(str(result),
+ "{'message': 'dummy output1', 'real_retcode': 1, 'retcode': 0}")
+
+ check_output_mock.reset_mock()
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/41b2d35f/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_nagios_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_nagios_server.py b/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_nagios_server.py
index d5a35bc..f1e4650 100644
--- a/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_nagios_server.py
+++ b/ambari-server/src/test/python/stacks/1.3.2/NAGIOS/test_nagios_server.py
@@ -245,13 +245,13 @@ class TestNagiosServer(RMFTestCase):
mode=0755
)
self.assertResourceCalled('File',
- '/usr/lib64/nagios/plugins/check_wrapper.sh',
- content=StaticFile('check_wrapper.sh'),
+ '/usr/lib64/nagios/plugins/hdp_nagios_init.php',
+ content=StaticFile('hdp_nagios_init.php'),
mode=0755
)
self.assertResourceCalled('File',
- '/usr/lib64/nagios/plugins/hdp_nagios_init.php',
- content=StaticFile('hdp_nagios_init.php'),
+ '/usr/lib64/nagios/plugins/mm_wrapper.py',
+ content=StaticFile('mm_wrapper.py'),
mode=0755
)
self.assertResourceCalled('File',