2016-03-23 17:25:18 +01:00
|
|
|
|
2016-04-01 15:51:45 +02:00
|
|
|
# Hardcoded variables
|
2016-04-07 13:23:11 +02:00
|
|
|
ZAF_VERSION="1.0"
|
2016-04-07 13:14:53 +02:00
|
|
|
ZAF_URL="https://github.com/limosek/zaf"
|
2016-04-08 23:26:46 +02:00
|
|
|
ZAF_RAW_URL="https://raw.githubusercontent.com/limosek/zaf"
|
2016-04-01 15:51:45 +02:00
|
|
|
|
2016-03-24 16:25:58 +01:00
|
|
|
############################################ Common routines
|
|
|
|
|
2016-03-24 20:37:03 +01:00
|
|
|
zaf_msg() {
|
2016-03-31 15:56:23 +02:00
|
|
|
echo $@
|
|
|
|
}
|
|
|
|
zaf_dbg() {
|
2016-04-04 10:27:25 +02:00
|
|
|
[ "$ZAF_DEBUG" -ge "2" ] && logger -s -t zaf -- $@
|
2016-03-31 15:56:23 +02:00
|
|
|
}
|
|
|
|
zaf_wrn() {
|
2016-04-04 10:27:25 +02:00
|
|
|
[ "$ZAF_DEBUG" -ge "1" ] && logger -s -t zaf -- $@
|
2016-03-31 15:56:23 +02:00
|
|
|
}
|
|
|
|
zaf_err() {
|
2016-04-04 10:27:25 +02:00
|
|
|
logger -s -t zaf -- $@
|
2016-03-31 15:56:23 +02:00
|
|
|
logger -s -t zaf "Exiting with error!"
|
|
|
|
exit 1
|
2016-03-24 20:37:03 +01:00
|
|
|
}
|
|
|
|
|
2016-04-01 15:51:45 +02:00
|
|
|
zaf_version(){
|
|
|
|
echo $ZAF_VERSION
|
|
|
|
}
|
|
|
|
|
2016-03-24 09:38:34 +01:00
|
|
|
# Fetch url to stdout
|
|
|
|
# $1 url
|
|
|
|
# It supports real file, file:// and other schemes known by curl
|
2016-03-23 17:25:18 +01:00
|
|
|
zaf_fetch_url() {
|
|
|
|
local scheme
|
|
|
|
local uri
|
2016-03-24 17:46:37 +01:00
|
|
|
local insecure
|
2016-03-23 17:25:18 +01:00
|
|
|
|
|
|
|
scheme=$(echo $1|cut -d ':' -f 1)
|
|
|
|
uri=$(echo $1|cut -d '/' -f 3-)
|
|
|
|
if [ "$1" = "$scheme" ]; then
|
|
|
|
cat "$1"
|
|
|
|
fi
|
|
|
|
case $scheme in
|
|
|
|
http|https|ftp|file)
|
2016-04-07 13:14:53 +02:00
|
|
|
[ "$scheme" != "file" ] && [ -n "$ZAF_OFFLINE" ] && zaf_err "Cannot download $1 in offline mode!"
|
2016-03-24 17:46:37 +01:00
|
|
|
[ "${ZAF_CURL_INSECURE}" = "1" ] && insecure="-k"
|
2016-04-04 10:27:25 +02:00
|
|
|
zaf_dbg curl $insecure -f -s -L -o - $1
|
2016-03-30 16:09:02 +02:00
|
|
|
curl $insecure -f -s -L -o - "$1"
|
2016-03-23 17:25:18 +01:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2016-03-24 09:38:34 +01:00
|
|
|
# Find and replace string
|
2016-03-23 17:25:18 +01:00
|
|
|
zaf_far(){
|
|
|
|
local f
|
|
|
|
local t
|
|
|
|
local sedcmd="sed"
|
|
|
|
i=1
|
|
|
|
while [ "$i" -lt "$#" ];
|
|
|
|
do
|
|
|
|
eval f=\$${i}
|
|
|
|
i=$(expr $i + 1)
|
|
|
|
eval t=\$${i}
|
|
|
|
i=$(expr $i + 1)
|
|
|
|
sedcmd="$sedcmd -e 's~$f~$t~g'"
|
|
|
|
done
|
|
|
|
eval $sedcmd
|
|
|
|
}
|
|
|
|
|
2016-03-24 16:25:58 +01:00
|
|
|
# Initialises discovery function
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_discovery_begin(){
|
|
|
|
cat <<EOF
|
|
|
|
{
|
|
|
|
"data":[
|
|
|
|
EOF
|
2016-03-24 16:25:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Add row(s) to discovery data
|
|
|
|
zaf_discovery_add_row(){
|
2016-04-01 12:20:23 +02:00
|
|
|
local rows
|
|
|
|
local row
|
|
|
|
|
|
|
|
rows=$1
|
|
|
|
row=$2
|
|
|
|
shift;shift
|
|
|
|
echo " {"
|
2016-03-24 16:25:58 +01:00
|
|
|
while [ -n "$1" ]; do
|
2016-04-01 15:51:45 +02:00
|
|
|
echo -n ' "'$1'":"'$2'" '
|
2016-04-01 12:20:23 +02:00
|
|
|
shift;shift
|
|
|
|
if [ -n "$1" ]; then
|
|
|
|
echo ","
|
|
|
|
else
|
|
|
|
echo ""
|
|
|
|
fi
|
2016-03-24 16:25:58 +01:00
|
|
|
done
|
2016-04-01 12:20:23 +02:00
|
|
|
if [ "$row" -lt "$rows" ]; then
|
|
|
|
echo " },"
|
|
|
|
else
|
|
|
|
echo " }"
|
|
|
|
fi
|
2016-03-24 16:25:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Dumps json object
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_discovery_end(){
|
|
|
|
cat <<EOF
|
|
|
|
]
|
|
|
|
}
|
|
|
|
EOF
|
2016-03-24 16:25:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Read standard input as discovery data. Columns are divided by space.
|
|
|
|
# Arguments are name of variables to discovery.
|
|
|
|
# Dumps json to stdout
|
|
|
|
zaf_discovery(){
|
2016-04-01 12:20:23 +02:00
|
|
|
local tmpfile
|
|
|
|
local rows
|
|
|
|
local a b c d e f g h i j row
|
|
|
|
|
|
|
|
tmpfile="${ZAF_TMP_DIR}/disc$$"
|
|
|
|
cat >$tmpfile
|
|
|
|
rows=$(wc -l <$tmpfile)
|
2016-03-24 16:25:58 +01:00
|
|
|
local a b c d e f g h i j;
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_discovery_begin
|
|
|
|
row=1
|
2016-03-24 16:25:58 +01:00
|
|
|
while read a b c d e f g h i j; do
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_discovery_add_row "$rows" "$row" "$1" "${1:+${a}}" "$2" "${2:+${b}}" "$3" "${3:+${c}}" "$4" "${4:+${d}}" "$5" "${5:+${e}}" "$6" "${6:+${f}}" "$7" "${7:+${g}}" "$8" "${8:+${h}}" "$9" "${9:+${i}}"
|
|
|
|
row=$(expr $row + 1)
|
|
|
|
done <$tmpfile
|
|
|
|
zaf_discovery_end
|
|
|
|
rm -f $tmpfile
|
2016-03-24 16:25:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
############################################ Zaf internal routines
|
|
|
|
|
2016-03-24 09:38:34 +01:00
|
|
|
# Restart zabbix agent
|
2016-03-23 17:25:18 +01:00
|
|
|
zaf_restart_agent() {
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_wrn "Restarting agent (${ZAF_AGENT_RESTART})"
|
2016-04-07 13:14:53 +02:00
|
|
|
${ZAF_AGENT_RESTART} || zaf_err "Cannot restart Zabbix agent (${ZAF_AGENT_RESTART}). Try $ZAF_AGENT_BIN -f !";
|
2016-03-23 17:25:18 +01:00
|
|
|
}
|
|
|
|
|
2016-03-24 09:38:34 +01:00
|
|
|
# Check if zaf.version item is populated
|
2016-03-23 17:25:18 +01:00
|
|
|
zaf_check_agent_config() {
|
|
|
|
zaf_restart_agent
|
2016-03-31 15:56:23 +02:00
|
|
|
${ZAF_AGENT_BIN} -t zaf.version
|
2016-03-23 17:25:18 +01:00
|
|
|
}
|
|
|
|
|
2016-03-23 14:37:51 +01:00
|
|
|
# Update repo
|
|
|
|
zaf_update_repo() {
|
2016-04-08 17:33:46 +02:00
|
|
|
[ "$ZAF_GIT" != 1 ] && { zaf_err "Git is disabled or is not installed. Exiting."; }
|
2016-04-08 23:19:19 +02:00
|
|
|
if [ -z "${ZAF_REPO_GITURL}" ] || [ -z "${ZAF_REPO_DIR}" ]; then
|
2016-04-01 15:51:45 +02:00
|
|
|
zaf_err "This system is not configured for git repository."
|
|
|
|
else
|
2016-04-08 23:19:19 +02:00
|
|
|
[ ! -d "${ZAF_REPO_DIR}" ] && git clone "${ZAF_REPO_GITURL}" "${ZAF_REPO_DIR}"
|
2016-04-01 15:51:45 +02:00
|
|
|
(cd ${ZAF_REPO_DIR} && git pull)
|
|
|
|
fi
|
2016-03-23 14:37:51 +01:00
|
|
|
}
|
|
|
|
|
2016-03-30 16:09:02 +02:00
|
|
|
# Construct url from plugin name
|
|
|
|
# It can be http[s]://url
|
|
|
|
# /path (from file)
|
|
|
|
# name (to try from repo)
|
|
|
|
zaf_get_plugin_url() {
|
2016-03-23 17:25:18 +01:00
|
|
|
local url
|
2016-04-07 13:14:53 +02:00
|
|
|
|
2016-03-24 17:46:37 +01:00
|
|
|
if echo "$1" | grep -q '/'; then
|
2016-04-01 12:20:23 +02:00
|
|
|
url="$1" # plugin with path - from directory
|
2016-03-23 17:25:18 +01:00
|
|
|
else
|
2016-03-24 17:46:37 +01:00
|
|
|
if echo "$1" | grep -q ^http; then
|
|
|
|
url="$1" # plugin with http[s] url
|
|
|
|
else
|
|
|
|
if [ -d "${ZAF_REPO_DIR}/$1" ]; then
|
|
|
|
url="${ZAF_REPO_DIR}/$1"
|
|
|
|
else
|
2016-04-07 13:14:53 +02:00
|
|
|
if [ -n "${ZAF_PREPACKAGED_DIR}" ] && [ -d "${ZAF_PREPACKAGED_DIR}/$1" ]; then
|
|
|
|
url="${ZAF_PREPACKAGED_DIR}/$1"
|
|
|
|
else
|
2016-04-08 23:19:19 +02:00
|
|
|
if [ -n "${ZAF_REPO_URL}" ]; then
|
|
|
|
url="${ZAF_REPO_URL}/$1"
|
|
|
|
else
|
|
|
|
zaf_err "Cannot find plugin $1"
|
|
|
|
fi
|
2016-04-07 13:14:53 +02:00
|
|
|
fi
|
2016-03-24 17:46:37 +01:00
|
|
|
fi
|
|
|
|
fi
|
2016-03-23 17:25:18 +01:00
|
|
|
fi
|
2016-03-30 16:09:02 +02:00
|
|
|
echo $url
|
|
|
|
}
|
|
|
|
|
|
|
|
# $1 - control
|
|
|
|
zaf_plugin_info() {
|
|
|
|
local control="$1"
|
|
|
|
|
2016-04-08 23:19:19 +02:00
|
|
|
! [ -f "$control" ] && zaf_err "Control file $control not found."
|
2016-03-30 16:09:02 +02:00
|
|
|
plugin=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Plugin)
|
|
|
|
pdescription=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_moption Description)
|
|
|
|
pmaintainer=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Maintainer)
|
|
|
|
pversion=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Version)
|
|
|
|
purl=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Url)
|
|
|
|
phome=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Home)
|
|
|
|
pitems=$(zaf_ctrl_get_items <"${control}")
|
|
|
|
echo
|
2016-04-01 12:20:23 +02:00
|
|
|
echo -n "Plugin '$plugin' "; [ -n "$pversion" ] && echo -n "version ${pversion}"; echo ":"
|
2016-03-30 16:09:02 +02:00
|
|
|
echo "$pdescription"; echo
|
|
|
|
[ -n "$pmaintainer" ] && echo "Maintainer: $pmaintainer"
|
|
|
|
[ -n "$purl" ] && echo "Url: $purl"
|
|
|
|
[ -n "$phome" ] && echo "Home: $phome"
|
|
|
|
echo
|
|
|
|
echo "Items: $pitems"
|
|
|
|
echo
|
|
|
|
}
|
|
|
|
|
2016-04-01 12:20:23 +02:00
|
|
|
# Prepare plugin into dir
|
2016-03-30 16:09:02 +02:00
|
|
|
# $1 is url, directory or plugin name (will be searched in default plugin dir).
|
|
|
|
# $2 is directory to prepare.
|
|
|
|
zaf_prepare_plugin() {
|
2016-04-04 14:00:44 +02:00
|
|
|
local url
|
|
|
|
local plugindir
|
|
|
|
local control
|
|
|
|
|
2016-04-08 23:19:19 +02:00
|
|
|
url=$(zaf_get_plugin_url "$1")/control.zaf || exit $?
|
2016-03-30 16:09:02 +02:00
|
|
|
plugindir="$2"
|
|
|
|
control=${plugindir}/control.zaf
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_install_dir "$plugindir"
|
2016-03-31 15:56:23 +02:00
|
|
|
zaf_dbg "Fetching control file from $url ..."
|
|
|
|
if zaf_fetch_url "$url" >"${control}"; then
|
2016-03-30 16:09:02 +02:00
|
|
|
zaf_ctrl_check_deps "${control}"
|
|
|
|
else
|
2016-04-08 23:19:19 +02:00
|
|
|
zaf_err "prepare_plugin: Cannot fetch or write control file $control from url $url!"
|
2016-03-30 16:09:02 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
zaf_install_plugin() {
|
2016-04-04 14:00:44 +02:00
|
|
|
local url
|
|
|
|
local plugin
|
|
|
|
local plugindir
|
|
|
|
local control
|
|
|
|
|
2016-03-30 16:09:02 +02:00
|
|
|
if zaf_prepare_plugin "$1" "${ZAF_TMP_DIR}/plugin"; then
|
2016-04-04 14:00:44 +02:00
|
|
|
url=$(zaf_get_plugin_url "$1")
|
2016-03-31 15:56:23 +02:00
|
|
|
plugin=$(zaf_ctrl_get_global_block <"${ZAF_TMP_DIR}/plugin/control.zaf" | zaf_block_get_option Plugin)
|
2016-03-30 16:09:02 +02:00
|
|
|
plugindir="${ZAF_PLUGINS_DIR}"/$plugin
|
2016-04-08 23:19:19 +02:00
|
|
|
if [ -n "$plugin" ] && zaf_prepare_plugin "$1" $plugindir; then
|
2016-04-04 14:00:44 +02:00
|
|
|
control=${plugindir}/control.zaf
|
2016-04-01 12:20:23 +02:00
|
|
|
[ "$ZAF_DEBUG" -gt 0 ] && zaf_plugin_info "${control}"
|
2016-03-30 16:09:02 +02:00
|
|
|
zaf_ctrl_check_deps "${control}"
|
2016-04-04 14:00:44 +02:00
|
|
|
zaf_ctrl_install "$url" "${control}" "${plugindir}"
|
2016-04-01 15:51:45 +02:00
|
|
|
zaf_ctrl_generate_cfg "${control}" "${plugin}" \
|
|
|
|
| zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_dbg "Generated ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf"
|
2016-03-24 15:46:42 +01:00
|
|
|
else
|
2016-04-08 23:19:19 +02:00
|
|
|
zaf_err "Cannot install plugin '$plugin' to $plugindir!"
|
2016-03-24 15:46:42 +01:00
|
|
|
fi
|
2016-03-31 15:56:23 +02:00
|
|
|
else
|
2016-04-01 12:20:23 +02:00
|
|
|
zaf_err "Cannot prepare plugin $1"
|
2016-03-23 17:25:18 +01:00
|
|
|
fi
|
2016-03-24 15:46:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# List installed plugins
|
|
|
|
# $1 - plugin
|
|
|
|
zaf_list_plugins() {
|
|
|
|
local cfile
|
|
|
|
local plugin
|
2016-04-01 12:20:23 +02:00
|
|
|
ls -1 ${ZAF_PLUGINS_DIR} | while read p; do
|
|
|
|
zaf_is_plugin "$(basename $p)" && echo $p
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
zaf_is_plugin() {
|
|
|
|
[ -d "$ZAF_PLUGINS_DIR/$1" ] && [ -f "$ZAF_PLUGINS_DIR/$1/control.zaf" ] && return
|
|
|
|
false
|
2016-03-24 15:46:42 +01:00
|
|
|
}
|
|
|
|
|
2016-03-24 17:26:34 +01:00
|
|
|
zaf_discovery_plugins() {
|
|
|
|
zaf_list_plugins | zaf_discovery '{#PLUGIN}'
|
|
|
|
}
|
|
|
|
|
|
|
|
zaf_plugin_version() {
|
2016-04-04 15:05:18 +02:00
|
|
|
local plugindir
|
|
|
|
local cfile
|
|
|
|
|
2016-03-24 17:26:34 +01:00
|
|
|
if [ -z "$1" ]; then
|
2016-04-04 15:05:18 +02:00
|
|
|
zaf_err "Missing plugin name.";
|
2016-03-24 17:26:34 +01:00
|
|
|
fi
|
2016-04-04 15:05:18 +02:00
|
|
|
if zaf_is_plugin "$1"; then
|
|
|
|
plugindir="${ZAF_PLUGINS_DIR}/$1"
|
|
|
|
cfile="$plugindir/control.zaf"
|
|
|
|
zaf_ctrl_get_global_option $cfile Version
|
2016-03-24 17:26:34 +01:00
|
|
|
else
|
2016-04-04 15:05:18 +02:00
|
|
|
zaf_err "Plugin $1 not installed."
|
2016-03-24 17:26:34 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-03-24 15:46:42 +01:00
|
|
|
zaf_list_plugin_items() {
|
2016-04-01 15:51:45 +02:00
|
|
|
local items
|
|
|
|
local i
|
|
|
|
local p
|
|
|
|
local key
|
|
|
|
|
|
|
|
if ! zaf_is_plugin "$1"; then
|
|
|
|
zaf_err "Missing plugin name or plugin $1 unknown. ";
|
2016-03-24 15:46:42 +01:00
|
|
|
fi
|
|
|
|
plugindir="${ZAF_PLUGINS_DIR}/$1"
|
2016-04-01 15:51:45 +02:00
|
|
|
cfile="$plugindir/control.zaf"
|
|
|
|
items=$(zaf_ctrl_get_items <$cfile)
|
|
|
|
for i in $items; do
|
|
|
|
p=$(zaf_ctrl_get_item_option $cfile $i "Parameters")
|
|
|
|
if [ -n "$p" ]; then
|
|
|
|
key="$1.$i[]"
|
|
|
|
else
|
|
|
|
key="$1.$i"
|
|
|
|
fi
|
|
|
|
echo -n "$key "
|
|
|
|
done
|
|
|
|
echo
|
2016-03-24 15:46:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
zaf_list_items() {
|
|
|
|
for p in $(zaf_list_plugins); do
|
2016-04-01 15:51:45 +02:00
|
|
|
echo $p: $(zaf_list_plugin_items $p)
|
2016-03-24 15:46:42 +01:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2016-04-08 17:33:46 +02:00
|
|
|
zaf_get_item() {
|
|
|
|
if which zabbix_get >/dev/null; then
|
|
|
|
zabbix_get -s localhost -k "$1" || zaf_wrn "Cannot reach agent on localhost. Please localhost to Server list."
|
|
|
|
return 11
|
|
|
|
else
|
|
|
|
zaf_wrn "Please install zabbix_get binary to check items over network."
|
|
|
|
return 11
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-04-01 15:51:45 +02:00
|
|
|
zaf_test_item() {
|
2016-04-08 17:33:46 +02:00
|
|
|
[ "$USER" != "zabbix" ] && zaf_wrn "You are not zabbix user. Test will be run with your privileges and sudo access!"
|
2016-04-01 15:51:45 +02:00
|
|
|
$ZAF_AGENT_BIN -t "$1"
|
|
|
|
}
|
|
|
|
|
2016-03-23 17:25:18 +01:00
|
|
|
zaf_remove_plugin() {
|
2016-04-01 12:20:23 +02:00
|
|
|
! [ -d ${ZAF_PLUGINS_DIR}/$1 ] && { zaf_err "Plugin $1 not installed!"; }
|
|
|
|
zaf_wrn "Removing plugin $1"
|
2016-03-23 17:25:18 +01:00
|
|
|
rm -rf ${ZAF_PLUGINS_DIR}/$1
|
|
|
|
rm -f ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf
|
2016-03-23 14:37:51 +01:00
|
|
|
}
|
2016-03-23 17:25:18 +01:00
|
|
|
|
|
|
|
|