1
0
mirror of https://github.com/limosek/zaf.git synced 2025-11-01 18:17:37 +01:00
This commit is contained in:
Lukas Macura
2016-04-14 21:38:22 +02:00
17 changed files with 1598 additions and 245 deletions

84
lib/cache.lib.sh Normal file
View File

@@ -0,0 +1,84 @@
# Zaf cache related functions
zaf_cache_clean(){
if [ -n "$ZAF_CACHE_DIR" ]; then
zaf_wrn "Removing cache entries"
rm -rf "$ZAF_CACHE_DIR"
else
zaf_err "Cache dir not set."
fi
mkdir -p "$ZAF_CACHE_DIR"
}
# Get cache key from requested param
zaf_cache_key(){
echo "$1" | md5sum - | cut -d ' ' -f 1
}
# Put object into cache
# $1 key
# $2 value
# $3 lifetime in seconds
zaf_tocache(){
! [ -w $ZAF_CACHE_DIR ] && return 1
local key
local value
key=$(zaf_cache_key "$1")
echo "$2" >$ZAF_CACHE_DIR/$key
echo "$1" >$ZAF_CACHE_DIR/$key.info
touch -m -d "$3 seconds" $ZAF_CACHE_DIR/$key.info
zaf_trc "Cache: Saving entry $1($key)"
}
# Put object into cache from stdin and copy to stdout
# $1 key
# $2 lifetime in seconds
zaf_tocache_stdin(){
! [ -w $ZAF_CACHE_DIR ] && return 1
local key
key=$(zaf_cache_key "$1")
cat >$ZAF_CACHE_DIR/$key
if [ -s $ZAF_CACHE_DIR/$key ]; then
zaf_trc "Cache: Saving entry $1($key)"
echo "$1" >$ZAF_CACHE_DIR/$key.info
touch -m -d "$2 seconds" $ZAF_CACHE_DIR/$key.info
cat $ZAF_CACHE_DIR/$key
else
rm $ZAF_CACHE_DIR/$key
fi
}
# Remove entry from cache
# $1 key
zaf_cache_delentry(){
! [ -w $ZAF_CACHE_DIR ] && return 1
local key
key=$(zaf_cache_key "$1")
zaf_trc "Cache: removing $1($key) from cache"
rm -f "$ZAF_CACHE_DIR/$key*"
}
# Get object from cache
# $1 key
zaf_fromcache(){
! [ -r $ZAF_CACHE_DIR ] || [ -n "$ZAF_NOCACHE" ] && return 1
local key
local value
key=$(zaf_cache_key "$1")
if [ -f $ZAF_CACHE_DIR/$key ]; then
if [ "$ZAF_CACHE_DIR/$key.info" -nt "$ZAF_CACHE_DIR/$key" ]; then
zaf_trc "Cache: serving $1($key) from cache"
cat $ZAF_CACHE_DIR/$key
else
zaf_trc "Cache: removing old entry $1"
rm -f "$ZAF_CACHE_DIR/$key*"
return 2
fi
else
zaf_trc "Cache: missing entry $1($key)"
return 1
fi
}

View File

@@ -55,33 +55,100 @@ zaf_block_get_option() {
# $1 - control file
# $2 - option name
zaf_ctrl_get_global_option() {
zaf_ctrl_get_global_block <$1 | zaf_block_get_moption "$2" \
|| zaf_ctrl_get_global_block <$1 | zaf_block_get_option "$2"
local ctrlvar
local ctrlopt
ctrlopt="ZAF_CTRL_$(zaf_stripctrl $2)"
eval ctrlvar=\$$ctrlopt
if [ -n "$ctrlvar" ]; then
zaf_dbg "Overriding control field $2 from env $ctrlopt($ctrlvar)"
echo $ctrlopt
else
zaf_ctrl_get_global_block <$1 | zaf_block_get_moption "$2" \
|| zaf_ctrl_get_global_block <$1 | zaf_block_get_option "$2"
fi
}
# Get item specific option (single or multiline)
# $1 - control file
# $2 - item name
# $3 - option name
zaf_ctrl_get_item_option() {
zaf_ctrl_get_item_block <$1 "$2" | zaf_block_get_moption "$3" \
|| zaf_ctrl_get_item_block <$1 "$2" | zaf_block_get_option "$3"
local ctrlvar
local ctrlopt
ctrlopt="ZAF_CTRLI_$(zaf_stripctrl $2)_$(zaf_stripctrl $3)"
eval ctrlvar=\$$ctrlopt
if [ -n "$ctrlvar" ]; then
zaf_dbg "Overriding item control field $2/$3 from env $ctrlopt($ctrlvar)"
echo $ctrlopt
else
zaf_ctrl_get_item_block <$1 "$2" | zaf_block_get_moption "$3" \
|| zaf_ctrl_get_item_block <$1 "$2" | zaf_block_get_option "$3"
fi
}
# Check dependencies based on control file
zaf_ctrl_check_deps() {
local deps
deps=$(zaf_ctrl_get_global_block <$1 | zaf_block_get_option "Depends-${ZAF_PKG}" )
zaf_os_specific zaf_check_deps $deps
if ! zaf_os_specific zaf_check_deps $deps; then
zaf_err "Missing one of dependend system packages: $deps"
fi
deps=$(zaf_ctrl_get_global_block <$1 | zaf_block_get_option "Depends-bin" )
for cmd in $deps; do
if ! which $cmd >/dev/null; then
zaf_wrn "Missing binary dependency $cmd. Please install it first."
return 1
zaf_err "Missing binary dependency $cmd. Please install it first."
fi
done
}
# Install binaries from control
# Install sudo config from control
# $1 plugin
# $2 control
# $3 plugindir
zaf_ctrl_sudo() {
local pdir
local plugin
local sudo
local cmd
local parms
pdir="$3"
plugin=$1
zaf_dbg "Installing sudoers entry $ZAF_SUDOERSD/zaf_$plugin"
sudo=$(zaf_ctrl_get_global_option $2 "Sudo" | zaf_far '{PLUGINDIR}' "${plugindir}")
[ -z "$sudo" ] && return # Nothing to install
if ! which sudo >/dev/null; then
zaf_wrn "Sudo needed bud not installed?"
fi
cmd=$(echo $sudo | cut -d ' ' -f 1)
parms=$(echo $sudo | cut -d ' ' -f 2-)
if which $cmd >/dev/null ; then
(echo "zabbix ALL=NOPASSWD:SETENV: $(which $cmd) $(echo $parms | tr '%' '*')";echo) >$ZAF_SUDOERSD/zaf_$plugin || zaf_err "Error during zaf_ctrl_sudo"
chmod 0440 $ZAF_SUDOERSD/zaf_$plugin
else
zaf_err "Cannot find binary '$cmd' to put into sudoers."
fi
}
# Install crontab config from control
# $1 plugin
# $2 control
# $3 plugindir
zaf_ctrl_cron() {
local pdir
local plugin
local cron
pdir="$3"
plugin=$1
zaf_dbg "Installing cron entry $ZAF_CROND/zaf_$plugin"
cron=$(zaf_ctrl_get_global_option $2 "Cron")
[ -z "$cron" ] && return # Nothing to install
zaf_ctrl_get_global_option $2 "Cron" | zaf_far '{PLUGINDIR}' "${plugindir}" >$ZAF_CROND/zaf_$plugin || zaf_err "Error during zaf_ctrl_cron"
}
# Install files defined to be installed in control to plugun directory
# $1 pluginurl
# $2 control
# $3 plugindir
@@ -89,18 +156,26 @@ zaf_ctrl_install() {
local binaries
local pdir
local script
local cmd
local files
local f
local b
pdir="$3"
binaries=$(zaf_ctrl_get_global_block <$2 | zaf_block_get_option "Install-bin")
(set -e
binaries=$(zaf_ctrl_get_global_option $2 "Install-bin")
for b in $binaries; do
zaf_fetch_url "$1/$b" >"${ZAF_TMP_DIR}/$b"
zaf_install_bin "${ZAF_TMP_DIR}/$b" "$pdir"
done
script=$(zaf_ctrl_get_global_block <$2 | zaf_block_get_moption "Install-script")
files=$(zaf_ctrl_get_global_option $2 "Install-files")
for f in $files; do
zaf_fetch_url "$1/$b" >"${ZAF_TMP_DIR}/$b"
zaf_install "${ZAF_TMP_DIR}/$b" "$pdir"
done
script=$(zaf_ctrl_get_global_option $2 "Install-script")
[ -n "$script" ] && eval "$script"
cmd=$(zaf_ctrl_get_global_block <$2 | zaf_block_get_option "Install-cmd")
[ -n "$cmd" ] && $cmd
true
) || zaf_err "Error during zaf_ctrl_install"
}
# Generates zabbix cfg from control file
@@ -112,13 +187,21 @@ zaf_ctrl_generate_cfg() {
local iscript
local ikey
local lock
local cache
items=$(zaf_ctrl_get_items <"$1")
(set -e
for i in $items; do
iscript=$(echo $i | tr -d '[]*&;:')
iscript=$(zaf_stripctrl $i)
params=$(zaf_ctrl_get_item_option $1 $i "Parameters")
if [ -n "$params" ]; then
ikey="$2.$i[*]"
args=""
apos=1;
for p in $params; do
args="$args \$$apos"
apos=$(expr $apos + 1)
done
else
ikey="$2.$i"
fi
@@ -126,25 +209,30 @@ zaf_ctrl_generate_cfg() {
if [ -n "$lock" ]; then
lock="${ZAF_LIB_DIR}/zaflock $lock "
fi
cache=$(zaf_ctrl_get_item_option $1 $i "Cache")
if [ -n "$cache" ]; then
cache="_cache '$cache' "
fi
cmd=$(zaf_ctrl_get_item_option $1 $i "Cmd")
if [ -n "$cmd" ]; then
echo "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $lock$cmd";
$(which echo) "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $cache $lock$cmd";
continue
fi
cmd=$(zaf_ctrl_get_item_option $1 $i "Function")
if [ -n "$cmd" ]; then
echo "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $lock$cmd";
$(which echo) "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $cache $lock$cmd";
continue;
fi
cmd=$(zaf_ctrl_get_item_option $1 $i "Script")
if [ -n "$cmd" ]; then
zaf_ctrl_get_item_option $1 $i "Script" >${ZAF_TMP_DIR}/${iscript}.sh;
zaf_install_bin ${ZAF_TMP_DIR}/${ikey}.sh ${ZAF_PLUGINS_DIR}/$2/
echo "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $lock${ZAF_PLUGINS_DIR}/$2/${iscript}.sh";
zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/
$(which echo) "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $cache $lock${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args";
continue;
fi
zaf_err "Item $i declared in control file but has no Cmd, Function or Script!"
done
) || zaf_err "Error during zaf_ctrl_generate_cfg"
}

View File

@@ -8,26 +8,39 @@ zaf_configure_os_openwrt() {
ZAF_CURL_INSECURE=1
}
zaf_configure_os_freebsd() {
ZAF_AGENT_PKG="zabbix3-agent"
ZAF_AGENT_CONFIG="/usr/local/etc/zabbix3/zabbix_agentd.conf"
ZAF_AGENT_CONFIGD="/usr/local/etc/zabbix3/zabbix_agentd.conf.d/"
ZAF_AGENT_BIN="/usr/local/sbin/zabbix_agentd"
ZAF_AGENT_RESTART="service zabbix_agentd restart"
}
zaf_detect_system() {
if which dpkg >/dev/null; then
ZAF_PKG=dpkg
ZAF_OS=$(lsb_release -is|tr '[:upper:]' '[:lower:]')
ZAF_OS_CODENAME=$(lsb_release -cs|tr '[:upper:]' '[:lower:]')
ZAF_OS=$(lsb_release -is|zaf_tolower)
ZAF_OS_CODENAME=$(lsb_release -cs|zaf_tolower)
ZAF_CURL_INSECURE=0
ZAF_AGENT_PKG="zabbix-agent"
return
else if which rpm >/dev/null; then
ZAF_PKG="rpm"
ZAF_OS=$(lsb_release -is|tr '[:upper:]' '[:lower:]')
ZAF_OS_CODENAME=$(lsb_release -cs|tr '[:upper:]' '[:lower:]')
ZAF_OS=$(lsb_release -is|zaf_tolower)
ZAF_OS_CODENAME=$(lsb_release -cs|zaf_tolower)
ZAF_CURL_INSECURE=0
ZAF_AGENT_PKG="zabbix-agent"
return
else if which opkg >/dev/null; then
ZAF_PKG="opkg"
. /etc/openwrt_release
ZAF_OS="$(echo $DISTRIB_ID|tr '[:upper:]' '[:lower:]')"
ZAF_OS_CODENAME="$(echo $DISTRIB_CODENAME|tr '[:upper:]' '[:lower:]')"
ZAF_OS="$(echo $DISTRIB_ID|zaf_tolower)"
ZAF_OS_CODENAME="$(echo $DISTRIB_CODENAME|zaf_tolower)"
return
else if which pkg >/dev/null; then
ZAF_PKG="pkg"
ZAF_OS="freebsd"
ZAF_OS_CODENAME="$(freebsd-version|cut -d '-' -f 1)"
return
else
ZAF_PKG="unknown"
@@ -35,6 +48,7 @@ zaf_detect_system() {
ZAF_OS_CODENAME="unknown"
ZAF_AGENT_PKG=""
return
fi
fi
fi
fi
@@ -101,22 +115,31 @@ zaf_uninstall(){
# Automaticaly install agent on debian
# For another os, create similar function (install_zabbix_centos)
zaf_install_agent_debian() {
zaf_fetch_url "http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-1+${ZAF_CODENAME}_all.deb" >"/tmp/zaf-installer/zabbix-release_3.0-1+${ZAF_CODENAME}_all.deb" \
&& dpkg -i "/tmp/zaf-installer/zabbix-release_3.0-1+${ZAF_CODENAME}_all.deb" \
zaf_fetch_url "http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-1+${ZAF_OS_CODENAME}_all.deb" >"/tmp/zaf-installer/zabbix-release_3.0-1+${ZAF_OS_CODENAME}_all.deb" \
&& dpkg -i "/tmp/zaf-installer/zabbix-release_3.0-1+${ZAF_OS_CODENAME}_all.deb" \
&& apt-get update \
&& apt-get install $ZAF_AGENT_PKG
&& apt-get install -y -q $ZAF_AGENT_PKG
}
zaf_install_agent_opkg() {
opkg update && \
opkg install $ZAF_AGENT_PKG
}
# Check if dpkg dependency is met
# $* - packages
zaf_check_deps_dpkg() {
dpkg-query -f '${Package}\n' -W $* >/dev/null
for i in $*; do
dpkg-query -f '${Status},${Package}\n' -W $* 2>/dev/null | grep -q "^install ok"
done
}
# Check if dpkg dependency is met
# $* - packages
zaf_check_deps_rpm() {
rpm --quiet -qi $*
for i in $*; do
rpm --quiet -qi $i | grep -q $i
done
}
# Check if dpkg dependency is met
@@ -124,7 +147,16 @@ zaf_check_deps_rpm() {
zaf_check_deps_opkg() {
local p
for p in $*; do
opkg info $p | grep -q 'Package:' || { echo "Missing package $p" >&2; return 1; }
opkg info $p | grep -q 'Package:' || { return 1; }
done
}
# Check if pkg dependency is met
# $* - packages
zaf_check_deps_pkg() {
local p
for p in $*; do
pkg query -x "Package: %n" $p| grep -q 'Package:' || { return 1; }
done
}

View File

@@ -4,18 +4,34 @@
[ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf
ZAF_TMP_DIR="${ZAF_TMP_BASE}-${USER}"
[ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c
trap "rm -rif ${ZAF_TMP_DIR}" EXIT
! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}"
! [ -d "${ZAF_CACHE_DIR}" ] && mkdir "${ZAF_CACHE_DIR}"
[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1
. ${ZAF_LIB_DIR}/zaf.lib.sh
. ${ZAF_LIB_DIR}/ctrl.lib.sh
. ${ZAF_LIB_DIR}/os.lib.sh
. ${ZAF_LIB_DIR}/zbxapi.lib.sh
. ${ZAF_LIB_DIR}/cache.lib.sh
export ZAF_LIB_DIR
export ZAF_TMP_DIR
export ZAF_PLUGINS_DIR
[ -n "$*" ] && $@
if [ "$1" = "_cache" ] || [ "$1" = "_nocache" ] ; then
[ "$1" = "_nocache" ] && export ZAF_NOCACHE=1
shift
seconds=$1
shift
parms=$(echo $*|tr -d ' ')
if ! zaf_fromcache $parms; then
([ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ] && $@ ) | zaf_tocache_stdin $parms $seconds
fi
else
[ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ] && $@
fi

View File

@@ -1,21 +1,26 @@
# Hardcoded variables
ZAF_VERSION="trunk"
ZAF_URL="https://raw.githubusercontent.com/limosek/zaf/master/"
ZAF_VERSION="1.2"
ZAF_GITBRANCH="master"
ZAF_URL="https://github.com/limosek/zaf"
ZAF_RAW_URL="https://raw.githubusercontent.com/limosek/zaf"
############################################ Common routines
zaf_msg() {
echo $@
}
zaf_trc() {
[ "$ZAF_DEBUG" -ge "3" ] && logger -s -t zaf -- $@
}
zaf_dbg() {
[ "$ZAF_DEBUG" -ge "2" ] && logger -s -t zaf $@
[ "$ZAF_DEBUG" -ge "2" ] && logger -s -t zaf -- $@
}
zaf_wrn() {
[ "$ZAF_DEBUG" -ge "1" ] && logger -s -t zaf $@
[ "$ZAF_DEBUG" -ge "1" ] && logger -s -t zaf -- $@
}
zaf_err() {
logger -s -t zaf $@
logger -s -t zaf -- $@
logger -s -t zaf "Exiting with error!"
exit 1
}
@@ -31,7 +36,11 @@ zaf_fetch_url() {
local scheme
local uri
local insecure
local out
if zaf_fromcache "$1"; then
return
fi
scheme=$(echo $1|cut -d ':' -f 1)
uri=$(echo $1|cut -d '/' -f 3-)
if [ "$1" = "$scheme" ]; then
@@ -39,9 +48,10 @@ zaf_fetch_url() {
fi
case $scheme in
http|https|ftp|file)
[ "$scheme" != "file" ] && [ -n "$ZAF_OFFLINE" ] && zaf_err "Cannot download $1 in offline mode!"
[ "${ZAF_CURL_INSECURE}" = "1" ] && insecure="-k"
zaf_msg curl $insecure -f -s -L -o - "$1"
curl $insecure -f -s -L -o - "$1"
zaf_dbg curl $insecure -f -s -L -o - $1
curl $insecure -f -s -L -o - "$1" | zaf_tocache_stdin "$1" 120
;;
esac
}
@@ -63,6 +73,28 @@ zaf_far(){
eval $sedcmd
}
# Limit concurrent processes or continue
zaf_bglimit(){
local maxbg
local maxnumber
local cnumber
[ -z "$BASH_VERSION" ] && { zaf_dbg "Job server not available. Use bash!"; return 1; }
if [ $# -eq 0 ] ; then
maxbg=5
else
maxbg=$1
fi
maxnumber=$((0 + ${1:-0}))
while true; do
cnumber=$(jobs | wc -l)
if [ $cnumber -lt $maxnumber ]; then
break
fi
zaf_dbg "Limiting next job due to $maxbg limit of bg jobs"
sleep 1
done
}
# Initialises discovery function
zaf_discovery_begin(){
cat <<EOF
@@ -131,7 +163,7 @@ zaf_discovery(){
# Restart zabbix agent
zaf_restart_agent() {
zaf_wrn "Restarting agent (${ZAF_AGENT_RESTART})"
${ZAF_AGENT_RESTART} || zaf_err "Cannot restart Zabbix agent (${ZAF_AGENT_RESTART})!"
${ZAF_AGENT_RESTART} || zaf_err "Cannot restart Zabbix agent (${ZAF_AGENT_RESTART}). Try $ZAF_AGENT_BIN -f !";
}
# Check if zaf.version item is populated
@@ -142,11 +174,11 @@ zaf_check_agent_config() {
# Update repo
zaf_update_repo() {
[ "$ZAF_GIT" != 1 ] && { zaf_err "Git is not installed. Exiting."; }
if [ -z "${ZAF_PLUGINS_GITURL}" ] || [ -z "${ZAF_REPO_DIR}" ]; then
[ "$ZAF_GIT" != 1 ] && { zaf_err "Git is disabled or is not installed. Exiting."; }
if [ -z "${ZAF_REPO_GITURL}" ] || [ -z "${ZAF_REPO_DIR}" ]; then
zaf_err "This system is not configured for git repository."
else
[ ! -d "${ZAF_REPO_DIR}" ] && git clone "${ZAF_PLUGINS_GITURL}" "${ZAF_REPO_DIR}"
[ ! -d "${ZAF_REPO_DIR}" ] && git clone "${ZAF_REPO_GITURL}" "${ZAF_REPO_DIR}"
(cd ${ZAF_REPO_DIR} && git pull)
fi
}
@@ -157,6 +189,7 @@ zaf_update_repo() {
# name (to try from repo)
zaf_get_plugin_url() {
local url
if echo "$1" | grep -q '/'; then
url="$1" # plugin with path - from directory
else
@@ -166,7 +199,15 @@ zaf_get_plugin_url() {
if [ -d "${ZAF_REPO_DIR}/$1" ]; then
url="${ZAF_REPO_DIR}/$1"
else
url="${ZAF_PLUGINS_URL}/$1";
if [ -n "${ZAF_PREPACKAGED_DIR}" ] && [ -d "${ZAF_PREPACKAGED_DIR}/$1" ]; then
url="${ZAF_PREPACKAGED_DIR}/$1"
else
if [ -n "${ZAF_REPO_URL}" ]; then
url="${ZAF_REPO_URL}/$1"
else
zaf_err "Cannot find plugin $1"
fi
fi
fi
fi
fi
@@ -177,6 +218,7 @@ zaf_get_plugin_url() {
zaf_plugin_info() {
local control="$1"
! [ -f "$control" ] && zaf_err "Control file $control not found."
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)
@@ -190,8 +232,14 @@ zaf_plugin_info() {
[ -n "$pmaintainer" ] && echo "Maintainer: $pmaintainer"
[ -n "$purl" ] && echo "Url: $purl"
[ -n "$phome" ] && echo "Home: $phome"
echo
echo "Items: $pitems"
echo
if zaf_is_plugin "$(basename $plugin)"; then
echo -n "Defined items: "; zaf_list_plugin_items $plugin
echo -n "Test items: "; zaf_list_plugin_items $plugin test
echo -n "Precache items: "; zaf_list_plugin_items $plugin precache
else
echo "Items: $pitems"
fi
echo
}
@@ -199,7 +247,11 @@ zaf_plugin_info() {
# $1 is url, directory or plugin name (will be searched in default plugin dir).
# $2 is directory to prepare.
zaf_prepare_plugin() {
url=$(zaf_get_plugin_url "$1")/control.zaf
local url
local plugindir
local control
url=$(zaf_get_plugin_url "$1")/control.zaf || exit $?
plugindir="$2"
control=${plugindir}/control.zaf
zaf_install_dir "$plugindir"
@@ -207,23 +259,33 @@ zaf_prepare_plugin() {
if zaf_fetch_url "$url" >"${control}"; then
zaf_ctrl_check_deps "${control}"
else
zaf_err "Cannot fetch or write control file!"
zaf_err "prepare_plugin: Cannot fetch or write control file $control from url $url!"
fi
}
zaf_install_plugin() {
local url
local plugin
local plugindir
local control
if zaf_prepare_plugin "$1" "${ZAF_TMP_DIR}/plugin"; then
url=$(zaf_get_plugin_url "$1")
plugin=$(zaf_ctrl_get_global_block <"${ZAF_TMP_DIR}/plugin/control.zaf" | zaf_block_get_option Plugin)
plugindir="${ZAF_PLUGINS_DIR}"/$plugin
if zaf_prepare_plugin "$1" $plugindir; then
[ "$ZAF_DEBUG" -gt 0 ] && zaf_plugin_info "${control}"
if [ -n "$plugin" ] && zaf_prepare_plugin "$1" $plugindir; then
zaf_wrn "Installing plugin $plugin from $url to $plugindir"
control=${plugindir}/control.zaf
[ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}"
zaf_ctrl_check_deps "${control}"
zaf_ctrl_install "$1" "${control}" "${plugindir}"
zaf_ctrl_install "$url" "${control}" "${plugindir}"
zaf_ctrl_sudo "$plugin" "${control}" "${plugindir}"
zaf_ctrl_cron "$plugin" "${control}" "${plugindir}"
zaf_ctrl_generate_cfg "${control}" "${plugin}" \
| zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf
zaf_dbg "Generated ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf"
else
zaf_err "Cannot install plugin $plugin to $plugindir!"
zaf_err "Cannot install plugin '$plugin' to $plugindir!"
fi
else
zaf_err "Cannot prepare plugin $1"
@@ -249,25 +311,49 @@ zaf_discovery_plugins() {
zaf_list_plugins | zaf_discovery '{#PLUGIN}'
}
zaf_plugin_version() {
# $1 plugin
# $2 ctrl_option
zaf_plugin_option() {
local plugindir
local cfile
if [ -z "$1" ]; then
echo "Missing plugin name";
exit 1
zaf_err "Missing plugin name.";
fi
plugindir="${ZAF_PLUGINS_DIR}/$1"
cfile="$plugindir/control"
if [ -d "$plugindir" ] ; then
zaf_ctrl_get_option "$cfile" Version
if zaf_is_plugin "$1"; then
plugindir="${ZAF_PLUGINS_DIR}/$1"
cfile="$plugindir/control.zaf"
zaf_ctrl_get_global_option $cfile $2
else
echo "Plugin $1 not installed"
zaf_err "Plugin $1 not installed."
fi
}
zaf_plugin_version() {
zaf_plugin_option "$1" Version
}
zaf_plugin_maintainer() {
zaf_plugin_option "$1" Maintainer
}
zaf_plugin_url() {
zaf_plugin_option "$1" Url
}
zaf_plugin_web() {
zaf_plugin_option "$1" Web
}
zaf_plugin_template_url() {
echo $(zaf_plugin_option "$1" Url)/template.xml
}
# $1 plugin
# $2 test to get test items, precache to get items to precache
zaf_list_plugin_items() {
local items
local i
local p
local key
local testparms
local precache
if ! zaf_is_plugin "$1"; then
zaf_err "Missing plugin name or plugin $1 unknown. ";
@@ -277,12 +363,25 @@ zaf_list_plugin_items() {
items=$(zaf_ctrl_get_items <$cfile)
for i in $items; do
p=$(zaf_ctrl_get_item_option $cfile $i "Parameters")
testparms=$(zaf_ctrl_get_item_option $cfile $i "Testparameters")
precache=$(zaf_ctrl_get_item_option $cfile $i "Precache")
if [ -n "$p" ]; then
key="$1.$i[]"
if [ -n "$testparms" ] && [ "$2" = "test" ]; then
for tp in $testparms; do
echo -n "$1.$i[$tp] "
done
else
if [ -n "$precache" ] && [ "$2" = "precache" ]; then
for tp in $precache; do
echo -n "$1.$i[$tp] "
done
fi
[ "$2" != "test" ] && key="$1.$i[]"
fi
else
key="$1.$i"
fi
echo -n "$key "
[ "$2" != "precache" ] && echo -n "$key "
done
echo
}
@@ -293,15 +392,57 @@ zaf_list_items() {
done
}
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
}
zaf_test_item() {
$ZAF_AGENT_BIN -t "$1"
}
zaf_precache_item() {
cmd=$(grep "^UserParameter=$item" $ZAF_AGENT_CONFIGD/zaf*.conf | cut -d ',' -f 2- | sed -e "s/_cache/_nocache/")
zaf_wrn "Precaching item $item[$(echo $*| tr ' ' ',')] ($cmd)"
eval $cmd
}
zaf_remove_plugin() {
! [ -d ${ZAF_PLUGINS_DIR}/$1 ] && { zaf_err "Plugin $1 not installed!"; }
! zaf_is_plugin $1 && { zaf_err "Plugin $1 not installed!"; }
zaf_wrn "Removing plugin $1"
rm -rf ${ZAF_PLUGINS_DIR}/$1
rm -f ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf
rm -f ${ZAF_AGENT_CONFIGD}/zaf_$1.conf ${ZAF_CROND}/zaf_$1 ${ZAF_SUDOERSD}/zaf_$1
}
zaf_tolower() {
tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
}
zaf_toupper() {
tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
# Return simplified key with discarded special chars.
zaf_stripctrl() {
echo $1 | tr '[]*&;:.-' '________'
}
# Unescape string on stdin
# $1 - list of chars to unescape
zaf_strunescape() {
sed -e 's#\\\(['"$1"']\)#\1#g'
}
# Escape string on stdin
# $1 - list of chars to escape
zaf_strescape() {
sed -e 's#\(['"$1"']\)#\\\1#g'
}

360
lib/zbxapi.lib.sh Normal file
View File

@@ -0,0 +1,360 @@
# Call api function and use cache
# $1 - query string
zaf_zbxapi_do() {
local result
zaf_trc "Zabbix API: $1"
result=$(curl -s -f -L -X POST -H 'Content-Type: application/json-rpc' -d "$1" "$ZAF_ZBXAPI_URL")
if [ $? = 0 ] && echo $result | grep -q '"result":'; then
zaf_trc "API OK"
echo $result
else
zaf_err "Error processing API request. ($?,$result)"
fi
}
# Call api function and cache results
# $1 - query string
zaf_zbxapi_do_cache() {
local result
if ! zaf_fromcache "$1"; then
result=$(zaf_zbxapi_do "$1")
[ -n "$result" ] && zaf_tocache "$1" "$result" 60
echo $result
fi
}
# Extract result from JSON response
zaf_zbxapi_getresult() {
sed -e 's/\({"jsonrpc":"2.0","result":\)\(.*\),\("id":.*\)/\2/g' | sed -e 's/^\[\]$//'
}
# Extract XML result from JSON response
zaf_zbxapi_getxml() {
zaf_zbxapi_getresult | sed -e 's/{"jsonrpc":"2.0","result":"//' | sed -e 's/","id"\:1}//' | zaf_zbxapi_getstring | zaf_strunescape '<">/'
}
# Extract string from JSON response result
zaf_zbxapi_getstring() {
sed -e 's/^"//' -e 's/"$//' -e 's/\\n/'\\n'/g'
}
# Extract value from JSON response result
# $1 key
zaf_zbxapi_getvalue() {
tr ',' '\n' | grep "\"$1\":" | cut -d '"' -f 4
}
# Zabbix API related functions
# Parameters in global variables ZAF_ZBX_API_*
# returns auth on stdout or false
zaf_zbxapi_login(){
local authstr
local user
local pass
local result
[ -z "$ZAF_ZBXAPI_URL" ] || [ -z "$ZAF_ZBXAPI_USER" ] || [ -z "$ZAF_ZBXAPI_PASS" ] && zaf_err "Zabbix Api parameters not set!"
authstr='{
"method" : "user.login",
"params" : {
"password" : "'$ZAF_ZBXAPI_PASS'",
"user" : "'$ZAF_ZBXAPI_USER'"
},
"id" : 0,
"jsonrpc" : "2.0"
}'
if [ "$ZAF_ZBXAPI_AUTHTYPE" = "http" ] ; then
ZAF_ZBXAPI_URL=$(echo $ZAF_ZBXAPI_URL | cut -d '/' -f 1)//$ZAF_ZBXAPI_USER:$ZAF_ZBXAPI_PASS@$(echo $ZAF_ZBXAPI_URL | cut -d '/' -f 3-)
fi
result=$(zaf_zbxapi_do_cache "$authstr")
ZAF_ZBXAPI_AUTH=$(echo $result |zaf_zbxapi_getresult| zaf_zbxapi_getstring)
[ -z "$ZAF_ZBXAPI_AUTH" ] && zaf_err "Cannot login into API"
zaf_dbg "Logged into zabbix API ($ZAF_ZBXAPI_AUTH)"
}
# $1 hostgroup name
zaf_zbxapi_gethostgroupid() {
local hstr
local filter
local gfilter
local result
hstr='{
"method": "hostgroup.get",
"jsonrpc": "2.0",
"auth": "'$ZAF_ZBXAPI_AUTH'",
"params": {
"filter": {
"name": ["'$1'"]
},
"output": "shorten"
},
"id": 1
}'
result=$(zaf_zbxapi_do_cache "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4)
[ -z "$result" ] && zaf_err "HostGroup $1 not found!"
echo $result
}
# $1 hostname
zaf_zbxapi_gethostid() {
local hstr
local host
local groupid
local filter
local gfilter
local result
host="$1"
if [ -n "$host" ] ; then
filter='"filter": { "host": [ "'$host'" ] },'
fi
hstr='{
"method": "host.get",
"jsonrpc": "2.0",
"auth": "'$ZAF_ZBXAPI_AUTH'",
"params": {
'$filter'
"output": "shorten"
},
"id": 1
}'
result=$(zaf_zbxapi_do_cache "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4)
[ -z "$result" ] && zaf_err "Host $1 not found!"
echo $result
}
# $1 hostname
zaf_zbxapi_gettemplateid() {
local hstr
local host
local groupid
local filter
local gfilter
local result
host="$1"
if [ -n "$host" ] ; then
filter='"filter": { "host": [ "'$host'" ] },'
fi
hstr='{
"method": "template.get",
"jsonrpc": "2.0",
"auth": "'$ZAF_ZBXAPI_AUTH'",
"params": {
'$filter'
"output": "shorten"
},
"id": 1
}'
result=$(zaf_zbxapi_do_cache "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4)
[ -z "$result" ] && zaf_err "Template $1 not found!"
echo $result
}
# $1 hostid
zaf_zbxapi_gethost() {
local hstr
local host
local groupid
local filter
local gfilter
local result
hostid="$1"
if [ -n "$hostid" ] ; then
filter='"hostids": [ "'$hostid'" ],'
fi
hstr='{
"method": "host.get",
"jsonrpc": "2.0",
"auth": "'$ZAF_ZBXAPI_AUTH'",
"params": {
'$filter'
"output": "extend"
},
"id": 1
}'
result=$(zaf_zbxapi_do_cache "$hstr" | zaf_zbxapi_getresult | zaf_zbxapi_getvalue host)
[ -z "$result" ] && zaf_err "Hostid $1 not found!"
echo $result
}
# $1 templateid
zaf_zbxapi_gettemplate() {
local hstr
local host
local groupid
local filter
local gfilter
local result
hostid="$1"
if [ -n "$hostid" ] ; then
filter='"templateids": [ "'$hostid'" ],'
fi
hstr='{
"method": "template.get",
"jsonrpc": "2.0",
"auth": "'$ZAF_ZBXAPI_AUTH'",
"params": {
'$filter'
"output": "extend"
},
"id": 1
}'
result=$(zaf_zbxapi_do_cache "$hstr" | zaf_zbxapi_getresult | zaf_zbxapi_getvalue host)
[ -z "$result" ] && zaf_err "Templateid $1 not found!"
echo $result
}
# $1 hostgroupid
zaf_zbxapi_gethostsingroup() {
local hstr
local host
local groupid
local filter
local gfilter
groupid="$1"
if [ -n "$groupid" ]; then
gfilter='"groupids": [ "'$groupid'" ],'
fi
hstr='{
"method": "host.get",
"jsonrpc": "2.0",
"auth": "'$ZAF_ZBXAPI_AUTH'",
"params": {
'$gfilter'
'$filter'
"output": "shorten"
},
"id": 1
}'
zaf_zbxapi_do_cache "$hstr" | zaf_zbxapi_getresult | tr ',' '\n' | cut -d '"' -f 4
}
# Object backup
# $1 object
# $2 id
zaf_zbxapi_export_object(){
local bkpstr
local obj
local id
obj="$1"
id="$2"
bkpstr='
{
"method": "configuration.export",
"jsonrpc": "2.0",
"params": {
"options": {
"'$obj'": [
"'$id'"
]
},
"format": "xml"
},
"auth": "'$ZAF_ZBXAPI_AUTH'",
"id": 1
}'
zaf_zbxapi_do_cache "$bkpstr" | zaf_zbxapi_getxml
}
# Host backup
# $1 hostid
zaf_zbxapi_export_host(){
zaf_zbxapi_export_object hosts "$1"
}
# Template backup
# $1 templateid
zaf_zbxapi_export_template(){
zaf_zbxapi_export_object templates "$1"
}
# Map backup
# $1 mapid
zaf_zbxapi_export_map(){
zaf_zbxapi_export_object maps "$1"
}
# Import template into zabbix
# $1 template file or stdin
zaf_zbxapi_import_config(){
local xmlstr
local impstr
if [ -z "$1" ]; then
xmlstr=$(zaf_strescape '"')
else
! [ -f "$1" ] && return 1
xmlstr=$(zaf_strescape '"\n\r' <$1)
fi
impstr='
{
"method": "configuration.import",
"jsonrpc": "2.0",
"params": {
"format": "xml",
"rules": {
"applications": {
"createMissing": true,
"updateExisting": true
},
"discoveryRules": {
"createMissing": true,
"updateExisting": true
},
"graphs": {
"createMissing": true,
"updateExisting": true
},
"hosts": {
"createMissing": true,
"updateExisting": true
},
"items": {
"createMissing": true,
"updateExisting": true
},
"templates": {
"createMissing": true,
"updateExisting": true
},
"triggers": {
"createMissing": true,
"updateExisting": true
},
"maps": {
"createMissing": true,
"updateExisting": true
},
"screens": {
"createMissing": true,
"updateExisting": true
},
"items": {
"createMissing": true,
"updateExisting": true
},
"valueMaps": {
"createMissing": true,
"updateExisting": true
}
},
"source": "'$xmlstr'"
},
"auth": "'$ZAF_ZBXAPI_AUTH'",
"id": 3
}'
zaf_zbxapi_do "$impstr" | zaf_zbxapi_getresult | grep -q true
}