From 4af246412013dcd6020f3766fada7615ef12863a Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Mon, 18 Apr 2016 10:35:23 +0200 Subject: [PATCH 01/32] Updated README --- README.md | 88 +++++++++++++++++++++++++++++--------------------- install.sh | 2 +- lib/zaf.lib.sh | 2 +- 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 2ebffb5..bb684bf 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -# Zabbix Agent Framework +# Zabbix (Agent) Framework This tool is used to maintain external zabbix checks in *one place*. There are lot of places where it is possible to download many external checks. But there is problem with installation, update and centralised management. This tool should do all of this in easy steps. In future it can be *starting point* to install and configure zabbix agent on systems with one step. Primary goal is not to make all plugins available here but to be able to use any plugin and decentralized development. -If you are maintainer of some external check, it is enough to create zaf file in your repo and use zaf installer everywhere. +If you are maintainer of some external check, it is enough to create zaf file in your repo and use zaf installer everywhere. + +Next to this, this tool can even communicate with Zabbix API with *NO dependencies* to high level languages. Shell, sed and awk only. ## Motivation -Did you install lot of zabbix agents and try to setup similar common user parameters? Do you want to setup them all? Do you want to change some zabbix agent options on lot of system? Do you want to write your own simple check or discovery rule for zabbix and it is nightmare to deploy same script on more zabbix agents? Are you tired searching some system specific agent check and setup them individualy? +Did you install lot of zabbix agents and try to setup similar common user parameters? Do you want to setup them all? Do you want to change some zabbix agent options on lot of system? Do you want to write your own simple check or discovery rule for zabbix and it is nightmare to deploy same script on more zabbix agents? Are you tired searching some system specific agent check and setup them individualy? Do you want to auto simple backup all hosts in your zabbix to xml files? Or do you want to do some scripting on host depending on Zabbix server configuration? So zaf is here for you :) ## Features @@ -21,22 +23,23 @@ So zaf is here for you :) * Zabbix discovery simplification. Creating zabbix item for discovery is not so easy in shell based system and result is not nice. But you can use framework function to do so. * Zabbix agent autoinstallation and autoconfiguration suitable to use in puppet or another tool * OS packaging support +* Zabbix API support ## Installing Zaf You need to be root and you must have curl installed on your system. Depending on your system, github certificates may not be available so you have to use *-k* option for curl (insecure). Default installation type is silent. So there will be no questions and everything will be autodetected. This simple command should be used on most systems: ``` -curl -k https://raw.githubusercontent.com/limosek/zaf/1.1/install.sh | sh +curl -k https://raw.githubusercontent.com/limosek/zaf/1.2/install.sh | sh ``` ### Install options and autoconfiguration General parameters for install.sh on any system (simplest way how to install) ``` -curl -k https://raw.githubusercontent.com/limosek/zaf/1.1/install.sh | \ +curl -k https://raw.githubusercontent.com/limosek/zaf/1.2/install.sh | \ sh -s {auto|interactive|debug-auto|debug-interactive} [Agent-Options] [Zaf-Options] ``` or use git version: ``` -git clone https://github.com/limosek/zaf.git; cd zaf; git checkout 1.1 +git clone https://github.com/limosek/zaf.git; cd zaf; git checkout 1.2 ./install.sh {auto|interactive|debug-auto|debug-interactive} [Agent-Options] [Zaf-Options] Agent-Options: Z_Option=value [...] Zaf-Options: ZAF_OPT=value [...] @@ -67,7 +70,7 @@ Now everything was tested on Debian and OpenWrt. If somebody is interrested in, Suppose you want to autoinstall agent on clean system. You need only curl installed. Everything else is one-cmd process. This command will install zaf, install zabbix-agent if necessary and sets zabbix variables on agent to reach server. This command can be automatized by puppet or another deploying system. ``` -curl -k https://raw.githubusercontent.com/limosek/zaf/1.1/install.sh | sh -s auto \ +curl -k https://raw.githubusercontent.com/limosek/zaf/1.2/install.sh | sh -s auto \ Z_Server=zabbix.server.local \ Z_ServerActive=zabbix.server.local \ Z_HostnameItem=system.hostname Z_RefreshActiveChecks=60 \ @@ -79,10 +82,10 @@ You can make your own deb package with preconfigured option. It is up to you to ``` git clone https://github.com/limosek/zaf.git \ && cd zaf \ - && git checkout 1.1 \ + && git checkout 1.2 \ && git clone https://github.com/limosek/zaf-plugins.git \ && make deb PLUGINS="./zaf-plugins/fsx" IPLUGINS="zaf" ZAF_OPTIONS="ZAF_GIT=0" AGENT_OPTIONS="Z_Server=zabbix.server Z_ServerActive=zabbix.server Z_StartAgents=8" -sudo dpkg -i out/zaf-1.2master.deb +sudo dpkg -i out/zaf-1.2.deb ``` General usage: ``` @@ -126,37 +129,50 @@ Zaf binary can be installed on any system from openwrt to big system. It has min ./zaf ./zaf Version 1.2. Please use some of this commands: ./zaf Cmd [ZAF_OPTION=value] [ZAF_CTRL_Option=value] [ZAF_CTRLI_Item_Option=value] ... -Commands: -./zaf update To update repo (not plugins, similar to apt-get update) -./zaf upgrade To upgrade installed plugins from repo -./zaf plugins To list installed plugins -./zaf show [plugin] To show installed plugins or plugin info -./zaf items [plugin] To list all suported items [for plugin] -./zaf test [plugin[.item]] To test [all] suported items by zabbix_agentd [for plugin] -./zaf get [plugin[.item]] To test [all] suported items by zabbix_get [for plugin] -./zaf precache [plugin[.item]] To precache [all] suported items -./zaf install plugin To install plugin -./zaf remove plugin To remove plugin -./zaf api To zabbix API functions. See ./zaf api for more info. -./zaf userparms See userparms generated from zaf on stdout -./zaf agent-config Reconfigure zabbix userparms in /etc/zabbix/zabbix_agentd.d -./zaf self-upgrade To self-upgrade zaf -./zaf self-remove To self-remove zaf and its config -./zaf cache-clean To remove all entries from cache -``` +Plugin manipulation commands: +./zaf update To update repo (not plugins, similar to apt-get update) +./zaf upgrade To upgrade installed plugins from repo +./zaf install plugin To install plugin +./zaf remove plugin To remove plugin + +Plugin info commands: +./zaf plugins To list installed plugins +./zaf show [plugin] To show installed plugins or plugin info +./zaf items [plugin] To list all suported items [for plugin] + +Plugin diagnostic commands: +./zaf test [plugin[.item]] To test [all] suported items by zabbix_agentd [for plugin] +./zaf get [plugin[.item]] To test [all] suported items by zabbix_get [for plugin] +./zaf precache [plugin[.item]] To precache [all] suported items + +Zabbix API commands: +./zaf api To zabbix API functions. See ./zaf api for more info. + +Agent config info commands: +./zaf userparms See userparms generated from zaf on stdout +./zaf agent-config Reconfigure zabbix userparms in /etc/zabbix/zabbix_agentd.d + +Zaf related commands: +./zaf self-upgrade To self-upgrade zaf +./zaf self-remove To self-remove zaf and its config +./zaf cache-clean To remove all entries from cache + Zaf can even communicate with zabbix server using its API. If you set ZAF_ZBXAPI_URL, ZAF_ZBXAPI_USER and ZAF_ZBXAPI_PASS in /etc/zaf.conf, you can use it: ``` ./zaf api command [parameters] -hostid 'host' Get hostid from hostname -host 'hostid' Get hostname from hostid -hostgroupid 'hostgroup' Get hostgroup id from hostgroup -hosts 'hostgroup' Get hosts in group -export-hosts dir [hostgroup] Backup all hosts [in group] (get their config from zabbix and save to dir/hostname.xml) -export-host 'host' Backup host (get config from zabbix to stdout) -import-template {plugin|file} Import template for plugin or from file -export-template 'name' Export template to stdout -export-templates dir Export all template to dir +get-host-id host Get host id +get-byid-host id [property] Get host property from id. Leave empty property for JSON +get-template-id template Get template id +get-byid-template id [property] Get template property from id. Leave empty property for JSON +get-map-id map Get map id +get-byid-map id [property] Get map property from id. Leave empty property for JSON +get-inventory host [fields] Get inventory fields [or all fields] +export-hosts dir [hg] Backup all hosts [in group hg] (get their config from zabbix and save to dir/hostname.xml) +export-host host Backup host (get config from zabbix to stdout) +import-template {plugin|file} Import template for plugin or from file +export-template name Export template to stdout +export-templates dir Export all templates to dir ``` ### Installing plugin diff --git a/install.sh b/install.sh index 7978eb5..506bad9 100755 --- a/install.sh +++ b/install.sh @@ -6,7 +6,7 @@ if [ -z "$ZAF_URL" ]; then ZAF_URL="https://github.com/limosek/zaf/" fi -[ -z "$ZAF_GITBRANCH" ] && ZAF_GITBRANCH=1.1 +[ -z "$ZAF_GITBRANCH" ] && ZAF_GITBRANCH=1.2 # Lite version of zaf_fetch_url, full version will be loaded later zaf_fetch_url(){ diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index a9f80ae..e592495 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -1,7 +1,7 @@ # Hardcoded variables ZAF_VERSION="1.2" -ZAF_GITBRANCH="master" +ZAF_GITBRANCH="1.2" ZAF_URL="https://github.com/limosek/zaf" ZAF_RAW_URL="https://raw.githubusercontent.com/limosek/zaf" From a320c33d44b02a196524d66cd325eed7fd11101e Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Mon, 18 Apr 2016 10:51:39 +0200 Subject: [PATCH 02/32] Repaired typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb684bf..02d4fd8 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ Zaf related commands: ./zaf self-upgrade To self-upgrade zaf ./zaf self-remove To self-remove zaf and its config ./zaf cache-clean To remove all entries from cache - +``` Zaf can even communicate with zabbix server using its API. If you set ZAF_ZBXAPI_URL, ZAF_ZBXAPI_USER and ZAF_ZBXAPI_PASS in /etc/zaf.conf, you can use it: ``` From da87113b47c1cb87f5e391341627c9285a9c8a11 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Mon, 18 Apr 2016 11:51:24 +0200 Subject: [PATCH 03/32] Repaired postinst and dpkg check --- Makefile | 5 ++++- files/postinst.template | 7 ++++++- lib/os.lib.sh | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c06c9ab..9f76dcc 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,10 @@ deb-control: deb-scripts: @. lib/zaf.lib.sh; \ . lib/ctrl.lib.sh; \ - cat files/postinst.template | zaf_far '{PLUGINS}' "$(PLUGINS)" | zaf_far "{IPLUGINS}" "$(IPLUGINS)" | zaf_far '{ZAF_LIB_DIR}' "/usr/lib/zaf" >$(DEBIAN_CTRL)/postinst + cat files/postinst.template | \ + zaf_far '{PLUGINS}' "$$(for p in $(PLUGINS); do echo $$(basename $$p); done)" | \ + zaf_far '{IPLUGINS}' "$$(for p in $(IPLUGINS); do echo $$(basename $$p); done)" | \ + zaf_far '{ZAF_LIB_DIR}' "/usr/lib/zaf" >$(DEBIAN_CTRL)/postinst @chmod +x $(DEBIAN_CTRL)/postinst @cp files/preinst.template $(DEBIAN_CTRL)/preinst @chmod +x $(DEBIAN_CTRL)/preinst diff --git a/files/postinst.template b/files/postinst.template index 6c95d4b..6e2f66b 100644 --- a/files/postinst.template +++ b/files/postinst.template @@ -8,7 +8,12 @@ configure) . /usr/lib/zaf/os.lib.sh . /usr/lib/zaf/ctrl.lib.sh cd /usr/lib/zaf && /usr/lib/zaf/install.sh reconf - [ -n "{PLUGINS}" ] && zaf reinstall {PLUGINS} {IPLUGINS} + [ -n "{PLUGINS}" ] && for p in {PLUGINS}; do + if ! is_plugin $p;then + zaf install $ZAF_PREPACKAGED_DIR/$p; + fi + done + [ -n "{IPLUGINS}" ] && zaf reinstall {IPLUGINS} fi ;; esac diff --git a/lib/os.lib.sh b/lib/os.lib.sh index 48ea6a5..a8ba2f8 100644 --- a/lib/os.lib.sh +++ b/lib/os.lib.sh @@ -130,7 +130,7 @@ zaf_install_agent_opkg() { # $* - packages zaf_check_deps_dpkg() { for i in $*; do - dpkg-query -f '${Status},${Package}\n' -W $* 2>/dev/null | grep -q "^install ok" + dpkg-query -f '${Status},${Package}\n' -W $* 2>/dev/null | grep -q "^install ok installed" done } From 8ad723f45c083c0cce5150e6a7fb9811614d3ae3 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Mon, 18 Apr 2016 12:08:42 +0200 Subject: [PATCH 04/32] Added contrib for making deb packages --- Makefile | 4 +++- contrib/zafdeb.sh | 15 +++++++++++++++ files/postinst.template | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100755 contrib/zafdeb.sh diff --git a/Makefile b/Makefile index 9f76dcc..d0d6e02 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,9 @@ CONTROLFILES=$(foreach p,$(PLUGINS),$(p)/control.zaf) ZAF_EXPORT_OPTS=$(foreach o,$(ZAF_OPTIONS),$(shell echo $(o)|cut -d '=' -f 1)) DEBIAN_DIR=tmp/deb DEBIAN_CTRL=$(DEBIAN_DIR)/DEBIAN -DEBIAN_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.deb) +ifeq ($(DEBIAN_PKG),) + DEBIAN_PKG=$(shell . lib/zaf.lib.sh; echo out/zaf-$$ZAF_VERSION.deb) +endif ifeq ($(ZAF_DEBUG),) ZAF_DEBUG=0 endif diff --git a/contrib/zafdeb.sh b/contrib/zafdeb.sh new file mode 100755 index 0000000..059f32a --- /dev/null +++ b/contrib/zafdeb.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. lib/zaf.lib.sh + +! [ -d plugins ] && git clone https://github.com/limosek/zaf-plugins.git plugins + +make deb DEBIAN_PKG="out/zaf-$ZAF_VERSION-git.deb" \ + ZAF_OPTIONS="ZAF_GIT=1 ZAF_REPO_GITURL='https://github.com/limosek/zaf-plugins.git'" + +make deb DEBIAN_PKG="out/zaf-$ZAF_VERSION.deb" \ + ZAF_OPTIONS="ZAF_GIT=0" + +make deb DEBIAN_PKG="out/zaf-$ZAF_VERSION-all.deb" ZAF_OPTIONS="ZAF_GIT=0" \ + PLUGINS="./plugins/fsx ./plugins/openssh ./plugins/psx ./plugins/tcqos ./plugins/zaf ./plugins/fail2ban" + diff --git a/files/postinst.template b/files/postinst.template index 6e2f66b..07301f7 100644 --- a/files/postinst.template +++ b/files/postinst.template @@ -9,7 +9,7 @@ configure) . /usr/lib/zaf/ctrl.lib.sh cd /usr/lib/zaf && /usr/lib/zaf/install.sh reconf [ -n "{PLUGINS}" ] && for p in {PLUGINS}; do - if ! is_plugin $p;then + if ! zaf_is_plugin $p;then zaf install $ZAF_PREPACKAGED_DIR/$p; fi done From 84f7e55078486b68c853923417ac6e248cd6ae73 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Mon, 18 Apr 2016 12:58:49 +0200 Subject: [PATCH 05/32] Repaired error in exporting hosts --- zaf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/zaf b/zaf index 589e9da..d02bbde 100755 --- a/zaf +++ b/zaf @@ -307,19 +307,19 @@ api) shift hosts=$(zaf_zbxapi_gethostsingroup $gid) else - hosts=$(zaf_zbxapi_gethostid) + hosts=$(zaf_zbxapi_gethostids) fi zaf_wrn "Will backup this hosts: $hosts" zaf_wrn "Output dir: $dir" for h in $hosts; do if zaf_bglimit 5; then ( - hn=$(zaf_zbxapi_gethost $h) + hn=$(zaf_zbxapi_gethost $h name) zaf_wrn "Exporting host $hn($h)..." zaf_zbxapi_export_host $h >"$dir/$hn.xml" ) & else - hn=$(zaf_zbxapi_gethost $h) + hn=$(zaf_zbxapi_gethost $h name) zaf_wrn "Exporting host $hn($h)..." zaf_zbxapi_export_host $h >"$dir/$hn.xml" fi @@ -342,18 +342,18 @@ api) shift; shift [ -z "$1" ] && zaf_err "$0 api export-templates dir" dir="$1" - templates=$(zaf_zbxapi_gettemplateid) + templates=$(zaf_zbxapi_gettemplateids) zaf_wrn "Will backup this templates: $templates" zaf_wrn "Output dir: $dir" for t in $templates; do if zaf_bglimit 5; then ( - tn=$(zaf_zbxapi_gettemplate $t) + tn=$(zaf_zbxapi_gettemplate $t name) zaf_wrn "Exporting template $tn($t)..." zaf_zbxapi_export_template $t >"$dir/$tn.xml" ) & else - tn=$(zaf_zbxapi_gettemplate $t) + tn=$(zaf_zbxapi_gettemplate $t name) zaf_wrn "Exporting template $tn($t)..." zaf_zbxapi_export_template $t >"$dir/$tn.xml" fi From ddbdff55d91a104bad8e61b8fc7441fb488653d7 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 10:37:39 +0200 Subject: [PATCH 06/32] Repaired userparms creation and including libraries --- install.sh | 4 +++- lib/ctrl.lib.sh | 22 ++++++++++++++-------- lib/preload.sh | 15 +++------------ lib/zaf.lib.sh | 10 ++++++++-- lib/zafcache | 17 +++++++++++++++++ lib/zaflock | 7 ++----- zaf | 2 +- 7 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 lib/zafcache diff --git a/install.sh b/install.sh index 506bad9..baea979 100755 --- a/install.sh +++ b/install.sh @@ -281,7 +281,7 @@ zaf_install_all() { for i in lib/zaf.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh README.md; do zaf_install $i ${ZAF_LIB_DIR}/ || zaf_err "Error installing $i" done - for i in lib/zaflock lib/preload.sh; do + for i in lib/zaflock lib/zafcache lib/preload.sh; do zaf_install_bin $i ${ZAF_LIB_DIR}/ || zaf_err "Error installing $i" done zaf_install_dir ${ZAF_BIN_DIR} @@ -295,8 +295,10 @@ zaf_install_all() { zaf_postconfigure() { if zaf_is_root; then + ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf cache-clean [ "${ZAF_GIT}" = 1 ] && ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf update ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf reinstall zaf || zaf_err "Error installing zaf plugin." + ${INSTALL_PREFIX}/${ZAF_BIN_DIR}/zaf agent-config || zaf_err "Error configuring agent." if zaf_is_root && ! zaf_test_item zaf.framework_version; then echo "Something is wrong with zabbix agent config." echo "Ensure that zabbix_agentd reads ${ZAF_AGENT_CONFIG}" diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 8386ba6..4dc4a7c 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -8,7 +8,7 @@ zaf_ctrl_get_items() { # Get item body from stdin # $1 itemname zaf_ctrl_get_item_block() { - grep -v '^#' | awk '/^Item '$1'/ { i=0; + grep -vE '^#[a-zA-Z ]' | awk '/^Item '$1'/ { i=0; while (i==0) { getline; if (/^\/Item/) exit; @@ -22,7 +22,7 @@ zaf_ctrl_get_item_block() { # Get global plugin block body from stdin # $1 itemname zaf_ctrl_get_global_block() { - grep -v '^#' | awk '{ i=0; print $0; + grep -vE '^#[a-zA-Z ]' | awk '{ i=0; print $0; while (i==0) { getline; if (/^Item /) exit; @@ -33,7 +33,7 @@ zaf_ctrl_get_global_block() { # Get item multiline option # $1 optionname zaf_block_get_moption() { - awk '/^'$1'::$/ { i=0; print $0; + awk '/^'$1'::$/ { i=0; while (i==0) { getline; if (/^::$/) {i=1; continue;}; @@ -181,6 +181,7 @@ zaf_ctrl_install() { # Generates zabbix cfg from control file # $1 control # $2 pluginname +# $3 if nonempty, only return cfg, do not generate scripts zaf_ctrl_generate_cfg() { local items local cmd @@ -211,20 +212,25 @@ zaf_ctrl_generate_cfg() { fi cache=$(zaf_ctrl_get_item_option $1 $i "Cache") if [ -n "$cache" ]; then - cache="_cache '$cache' " + cache="${ZAF_LIB_DIR}/zafcache '$cache' " fi cmd=$(zaf_ctrl_get_item_option $1 $i "Cmd") + if [ -z "$cache" ] && [ -z "$lock" ]; then + preload="${ZAF_LIB_DIR}/preload.sh " + else + preload="" + fi if [ -n "$cmd" ]; then - $(which echo) "UserParameter=$ikey,${ZAF_LIB_DIR}/preload.sh $cache $lock$cmd"; + printf "%s" "UserParameter=$ikey,${preload}${cache}${lock}${cmd}"; echo continue fi cmd=$(zaf_ctrl_get_item_option $1 $i "Script") if [ -n "$cmd" ]; then zaf_ctrl_get_item_option $1 $i "Script" | \ - zaf_far '{INCLUDES}' '. /etc/zaf.conf; . ${ZAF_LIB_DIR}/zaf.lib.sh; . ${ZAF_LIB_DIR}/ctrl.lib.sh; . ${ZAF_LIB_DIR}/zbxapi.lib.sh; . ${ZAF_LIB_DIR}/cache.lib.sh; ' \ + zaf_far '{INCLUDES}' ". $ZAF_LIB_DIR/preload.sh; " \ >${ZAF_TMP_DIR}/${iscript}.sh; - zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ - $(which echo) "UserParameter=$ikey,$cache $lock${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args"; + [ -z "$3" ] && zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ + printf "%s" "UserParameter=$ikey,${preload}${cache}${lock}${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args"; echo continue; fi zaf_err "Item $i declared in control file but has no Cmd, Function or Script!" diff --git a/lib/preload.sh b/lib/preload.sh index 46a8881..ec182cf 100644 --- a/lib/preload.sh +++ b/lib/preload.sh @@ -19,19 +19,10 @@ trap "rm -rif ${ZAF_TMP_DIR}" EXIT export ZAF_LIB_DIR export ZAF_TMP_DIR +export ZAF_CACHE_DIR export ZAF_PLUGINS_DIR -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 +[ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ] && $@ + diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index e592495..b2244fe 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -412,7 +412,8 @@ zaf_list_items() { 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." + zaf_dbg zabbix_get -s localhost -k "'$1'" + (zabbix_get -s localhost -k "$1" | tr '\n' ' '; echo) || 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." @@ -421,7 +422,12 @@ zaf_get_item() { } zaf_test_item() { - $ZAF_AGENT_BIN -t "$1" + if $ZAF_AGENT_BIN -t "$1" | grep ZBX_NOTSUPPORTED; then + return 1 + else + $ZAF_AGENT_BIN -t "$1" | tr '\n' ' ' + echo + fi } zaf_precache_item() { diff --git a/lib/zafcache b/lib/zafcache new file mode 100644 index 0000000..0a98c2d --- /dev/null +++ b/lib/zafcache @@ -0,0 +1,17 @@ +#!/bin/sh + +. $(dirname $0)/preload.sh + +help() { + zaf_err "$0 seconds cmd..." +} + +seconds=$1 +shift +[ -z "$*" ] && help + +parms=$(echo $*|tr -d ' ') +if ! zaf_fromcache "$parms"; then + $@ | zaf_tocache_stdin "$parms" "$seconds" +fi + diff --git a/lib/zaflock b/lib/zaflock index 5c004b8..a983f94 100644 --- a/lib/zaflock +++ b/lib/zaflock @@ -1,12 +1,9 @@ #!/bin/sh -. /etc/zaf.conf - -. ${ZAF_LIB_DIR}/zaf.lib.sh +. $(dirname $0)/preload.sh help() { - echo "$0 key cmd" - exit 2 + zaf_err "$0 key cmd" } lkey="$1" diff --git a/zaf b/zaf index d02bbde..05ba1bf 100755 --- a/zaf +++ b/zaf @@ -77,7 +77,7 @@ userparms) for plugin in $(zaf_list_plugins); do plugindir=$ZAF_PLUGINS_DIR/$plugin control=$plugindir/control.zaf - zaf_ctrl_generate_cfg "${control}" "${plugin}" \ + zaf_ctrl_generate_cfg "${control}" "${plugin}" "noscripts" \ | zaf_far '{PLUGINDIR}' "${plugindir}" done ;; From 79b98bf661e8047cea7b24a66bbdea1daa6be8f2 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 11:09:22 +0200 Subject: [PATCH 07/32] Diagnostic changes Added support for detecting beesip os --- lib/os.lib.sh | 5 ++++- lib/zaf.lib.sh | 10 +++++----- zaf | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/os.lib.sh b/lib/os.lib.sh index a8ba2f8..792bce8 100644 --- a/lib/os.lib.sh +++ b/lib/os.lib.sh @@ -1,12 +1,15 @@ # Os related functions zaf_configure_os_openwrt() { - ZAF_AGENT_RESTART="/etc/init.d/zabbix_agentd restart" + ZAF_AGENT_RESTART="zaf agent-config; /etc/init.d/zabbix_agentd restart" ZAF_AGENT_CONFIGD="/var/run/zabbix_agentd.conf.d/" ZAF_AGENT_CONFIG="/etc/zabbix_agentd.conf" ZAF_AGENT_PKG="zabbix-agentd" ZAF_CURL_INSECURE=1 } +zaf_configure_os_beesip() { + zaf_configure_os_openwrt +} zaf_configure_os_freebsd() { ZAF_AGENT_PKG="zabbix3-agent" diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index b2244fe..7ba395b 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -11,17 +11,17 @@ zaf_msg() { echo $@ } zaf_trc() { - [ "$ZAF_DEBUG" -ge "3" ] && logger -s -t zaf -- $@ + [ "$ZAF_DEBUG" -ge "3" ] && logger -p user.info -s -t zaf-trace -- $@ } zaf_dbg() { - [ "$ZAF_DEBUG" -ge "2" ] && logger -s -t zaf -- $@ + [ "$ZAF_DEBUG" -ge "2" ] && logger -p user.debug -s -t zaf-debug -- $@ } zaf_wrn() { - [ "$ZAF_DEBUG" -ge "1" ] && logger -s -t zaf -- $@ + [ "$ZAF_DEBUG" -ge "1" ] && logger -p user.warn -s -t zaf-warning -- $@ } zaf_err() { - logger -s -t zaf -- $@ - logger -s -t zaf "Exiting with error!" + logger -s -p user.err -t zaf-error -- $@ + logger -s -p user.err -t zaf-error "Exiting with error!" exit 1 } # Help option diff --git a/zaf b/zaf index 05ba1bf..0013649 100755 --- a/zaf +++ b/zaf @@ -83,9 +83,11 @@ userparms) ;; agent-config) + zaf_wrn "Generating config files in $ZAF_AGENT_CONFIGD ..." for plugin in $(zaf_list_plugins); do plugindir=$ZAF_PLUGINS_DIR/$plugin control=$plugindir/control.zaf + zaf_dbg "Generating ${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf" zaf_ctrl_generate_cfg "${control}" "${plugin}" \ | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf done From 8578dba9506f7ade8ffc82d20b9f6ee4962c900d Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 11:12:06 +0200 Subject: [PATCH 08/32] Repaired typo --- lib/os.lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/os.lib.sh b/lib/os.lib.sh index 792bce8..744396a 100644 --- a/lib/os.lib.sh +++ b/lib/os.lib.sh @@ -1,7 +1,7 @@ # Os related functions zaf_configure_os_openwrt() { - ZAF_AGENT_RESTART="zaf agent-config; /etc/init.d/zabbix_agentd restart" + ZAF_AGENT_RESTART="zaf agent-config ; /etc/init.d/zabbix_agentd restart" ZAF_AGENT_CONFIGD="/var/run/zabbix_agentd.conf.d/" ZAF_AGENT_CONFIG="/etc/zabbix_agentd.conf" ZAF_AGENT_PKG="zabbix-agentd" From 122c6fc83118a92f2f6d6436702a0d63c6c8509e Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 11:31:23 +0200 Subject: [PATCH 09/32] Added diagnostic opts --- zaf | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/zaf b/zaf index 0013649..ce22d1e 100755 --- a/zaf +++ b/zaf @@ -65,14 +65,17 @@ fi case $1 in -check-agent-config) - zaf_check_agent_config - ;; - cache-clean) zaf_cache_clean ;; +version) + echo "$ZAF_VERSION" + [ $ZAF_DEBUG -gt 1 ] && set |grep -E ^ZAF_ + ;; + + +###### Agent related commands userparms) for plugin in $(zaf_list_plugins); do plugindir=$ZAF_PLUGINS_DIR/$plugin @@ -81,7 +84,6 @@ userparms) | zaf_far '{PLUGINDIR}' "${plugindir}" done ;; - agent-config) zaf_wrn "Generating config files in $ZAF_AGENT_CONFIGD ..." for plugin in $(zaf_list_plugins); do @@ -92,7 +94,11 @@ agent-config) | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf done ;; +check-agent-config) + zaf_check_agent_config + ;; +###### Plugins related commands update) zaf_wrn "Updating repository ${ZAF_REPO_GITURL}..." zaf_update_repo @@ -119,11 +125,9 @@ show) fi fi ;; - plugins) zaf_list_plugins ;; - items) shift if [ -z "$1" ]; then @@ -132,7 +136,6 @@ items) zaf_list_plugin_items "$1" fi ;; - test) [ "$USER" != "zabbix" ] && zaf_wrn "You are not zabbix user. Test will be run with your privileges and sudo access!" shift @@ -171,7 +174,6 @@ get) done done ;; - precache) shift for i in $*; do @@ -188,7 +190,6 @@ precache) fi done ;; - install) shift [ -z "$1" ] && echo "$0 install plugin [plugin]..." @@ -202,7 +203,6 @@ install) done [ -n "$installed" ] && zaf_is_root && zaf_restart_agent ;; - reinstall) shift [ -z "$1" ] && echo "$0 reinstall plugin [plugin]..." @@ -216,7 +216,6 @@ reinstall) done [ -n "$reinstalled" ] && zaf_is_root && zaf_restart_agent ;; - remove) shift [ -z "$1" ] && echo "$0 remove plugin [plugin]..." @@ -229,6 +228,7 @@ remove) [ -n "$removed" ] && zaf_is_root && zaf_restart_agent ;; +###### Zaf related commands self-upgrade) shift [ -z "$1" ] && auto=auto @@ -241,7 +241,6 @@ self-upgrade) zaf_fetch_url $ZAF_RAW_URL/$ZAF_GITBRANCH/install.sh | exec sh -s $auto "$@" exit ;; - self-remove) shift zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot self-remove." @@ -258,7 +257,7 @@ self-remove) echo "To continue, please do $0 self-remove force" fi ;; - +###### API related commands api) zaf_zbxapi_login case $2 in @@ -283,8 +282,13 @@ api) fi ;; get-inventory) - [ -z "$3" ] && zaf_err "$0 $1 [field]" - zaf_zbxapi_gethostinventory $3 $4 + [ -z "$3" ] && zaf_err "$0 $1 field [host]. If host unspecified, use hostname" + if [ -z "$4" ]; then + host=$(hostname) + else + host="$4" + fi + zaf_zbxapi_gethostinventory $host $3 ;; get-template-ids) if [ -n "$3" ]; then @@ -400,7 +404,7 @@ api) zaf_hlp "export-template name" "Export template to stdout" zaf_hlp "export-templates dir" "Export all template to dir" echo - exit + [ -n "$2" ] && zaf_err "Bad API command '$2'!" ;; esac ;; @@ -436,6 +440,7 @@ api) zaf_hlp "$0 self-remove" "To self-remove zaf and its config" zaf_hlp "$0 cache-clean" "To remove all entries from cache" echo + [ -n "$1" ] && zaf_err "Bad command '$1'!" ;; esac From b892cb067d67d81eabc1083742cf4643eed8aee6 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 12:35:20 +0200 Subject: [PATCH 10/32] Repaired plugin installation checks --- lib/ctrl.lib.sh | 2 ++ lib/zaf.lib.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 4dc4a7c..77cf2ef 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -115,6 +115,7 @@ zaf_ctrl_sudo() { pdir="$3" plugin=$1 + ! [ -d "$ZAF_SUDOERSD" ] && zaf_wrn "$ZAF_SUDOERSD nonexistent! Skipping sudo install!" 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 @@ -142,6 +143,7 @@ zaf_ctrl_cron() { pdir="$3" plugin=$1 + ! [ -d "$ZAF_CROND" ] && zaf_wrn "$ZAF_CROND nonexistent! Skipping cron install!" zaf_dbg "Installing cron entry $ZAF_CROND/zaf_$plugin" cron=$(zaf_ctrl_get_global_option $2 "Cron") [ -z "$cron" ] && return # Nothing to install diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 7ba395b..fc9322b 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -296,12 +296,12 @@ zaf_install_plugin() { control=${plugindir}/control.zaf [ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}" zaf_ctrl_check_deps "${control}" - 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" + zaf_ctrl_install "$url" "${control}" "${plugindir}" else zaf_err "Cannot install plugin '$plugin' to $plugindir!" fi From 941a96208c54b265683b66681811b5aabfda5833 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 12:37:37 +0200 Subject: [PATCH 11/32] One more check in installation --- lib/ctrl.lib.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 77cf2ef..275bd20 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -115,7 +115,7 @@ zaf_ctrl_sudo() { pdir="$3" plugin=$1 - ! [ -d "$ZAF_SUDOERSD" ] && zaf_wrn "$ZAF_SUDOERSD nonexistent! Skipping sudo install!" + ! [ -d "$ZAF_SUDOERSD" ] && { zaf_wrn "$ZAF_SUDOERSD nonexistent! Skipping sudo install!"; return 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 @@ -143,7 +143,7 @@ zaf_ctrl_cron() { pdir="$3" plugin=$1 - ! [ -d "$ZAF_CROND" ] && zaf_wrn "$ZAF_CROND nonexistent! Skipping cron install!" + ! [ -d "$ZAF_CROND" ] && { zaf_wrn "$ZAF_CROND nonexistent! Skipping cron install!"; return 1; } zaf_dbg "Installing cron entry $ZAF_CROND/zaf_$plugin" cron=$(zaf_ctrl_get_global_option $2 "Cron") [ -z "$cron" ] && return # Nothing to install From c5df62146126e7b136d0f7369876af627a09ddb4 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 15:48:12 +0200 Subject: [PATCH 12/32] Json parsing based on JSON.sh https://github.com/dominictarr/JSON.sh --- install.sh | 3 +- lib/JSON.sh | 208 ++++++++++++++++++++++++++++++++++++ lib/cache.lib.sh | 8 +- lib/plugin.lib.sh | 259 +++++++++++++++++++++++++++++++++++++++++++++ lib/zaf.lib.sh | 263 ++-------------------------------------------- lib/zbxapi.lib.sh | 61 ++++++----- zaf | 6 +- 7 files changed, 520 insertions(+), 288 deletions(-) create mode 100755 lib/JSON.sh create mode 100644 lib/plugin.lib.sh diff --git a/install.sh b/install.sh index baea979..b86a913 100755 --- a/install.sh +++ b/install.sh @@ -39,6 +39,7 @@ fi if ! type zaf_version >/dev/null; then . lib/zaf.lib.sh +. lib/plugin.lib.sh . lib/os.lib.sh . lib/ctrl.lib.sh . lib/cache.lib.sh @@ -278,7 +279,7 @@ zaf_install_all() { rm -rif ${ZAF_TMP_DIR} mkdir -p ${ZAF_TMP_DIR} zaf_install_dir ${ZAF_LIB_DIR} - for i in lib/zaf.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh README.md; do + for i in lib/zaf.lib.sh lib/plugin.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh lib/JSON.sh README.md; do zaf_install $i ${ZAF_LIB_DIR}/ || zaf_err "Error installing $i" done for i in lib/zaflock lib/zafcache lib/preload.sh; do diff --git a/lib/JSON.sh b/lib/JSON.sh new file mode 100755 index 0000000..d9b8056 --- /dev/null +++ b/lib/JSON.sh @@ -0,0 +1,208 @@ +#!/bin/sh + +throw() { + echo "$*" >&2 + exit 1 +} + +BRIEF=0 +LEAFONLY=0 +PRUNE=0 +NO_HEAD=0 +NORMALIZE_SOLIDUS=0 + +usage() { + echo + echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" + echo + echo "-p - Prune empty. Exclude fields with empty values." + echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." + echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." + echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." + echo "-s - Remove escaping of the solidus symbol (stright slash)." + echo "-h - This help text." + echo +} + +parse_options() { + set -- "$@" + local ARGN=$# + while [ "$ARGN" -ne 0 ] + do + case $1 in + -h) usage + exit 0 + ;; + -b) BRIEF=1 + LEAFONLY=1 + PRUNE=1 + ;; + -l) LEAFONLY=1 + ;; + -p) PRUNE=1 + ;; + -n) NO_HEAD=1 + ;; + -s) NORMALIZE_SOLIDUS=1 + ;; + ?*) echo "ERROR: Unknown option." + usage + exit 0 + ;; + esac + shift 1 + ARGN=$((ARGN-1)) + done +} + +awk_egrep () { + local pattern_string=$1 + + gawk '{ + while ($0) { + start=match($0, pattern); + token=substr($0, start, RLENGTH); + print token; + $0=substr($0, start+RLENGTH); + } + }' pattern="$pattern_string" +} + +tokenize () { + local GREP + local ESCAPE + local CHAR + + if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 + then + GREP='egrep -ao --color=never' + else + GREP='egrep -ao' + fi + + if echo "test string" | egrep -o "test" >/dev/null 2>&1 + then + ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\]' + else + GREP=awk_egrep + ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\\\]' + fi + + local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" + local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' + local KEYWORD='null|false|true' + local SPACE='[[:space:]]+' + + # Force zsh to expand $A into multiple words + local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') + if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi + $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" + if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi +} + +parse_array () { + local index=0 + local ary='' + read -r token + case "$token" in + ']') ;; + *) + while : + do + parse_value "$1" "$index" + index=$((index+1)) + ary="$ary""$value" + read -r token + case "$token" in + ']') break ;; + ',') ary="$ary," ;; + *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= + : +} + +parse_object () { + local key + local obj='' + read -r token + case "$token" in + '}') ;; + *) + while : + do + case "$token" in + '"'*'"') key=$token ;; + *) throw "EXPECTED string GOT ${token:-EOF}" ;; + esac + read -r token + case "$token" in + ':') ;; + *) throw "EXPECTED : GOT ${token:-EOF}" ;; + esac + read -r token + parse_value "$1" "$key" + obj="$obj$key:$value" + read -r token + case "$token" in + '}') break ;; + ',') obj="$obj," ;; + *) throw "EXPECTED , or } GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= + : +} + +parse_value () { + local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 + case "$token" in + '{') parse_object "$jpath" ;; + '[') parse_array "$jpath" ;; + # At this point, the only valid single-character tokens are digits. + ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; + *) value=$token + # if asked, replace solidus ("\/") in json strings with normalized value: "/" + [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') + isleaf=1 + [ "$value" = '""' ] && isempty=1 + ;; + esac + [ "$value" = '' ] && return + [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return + + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ + [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 + [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" + : +} + +parse () { + read -r token + parse_value + read -r token + case "$token" in + '') ;; + *) throw "EXPECTED EOF GOT $token" ;; + esac +} + +if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); +then + parse_options "$@" + tokenize | parse +fi + +# vi: expandtab sw=2 ts=2 diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index ebd02f5..8ae1378 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -23,11 +23,13 @@ zaf_tocache(){ ! [ -w $ZAF_CACHE_DIR ] && return 1 local key local value + local expiry 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 + expiry=$(zaf_date_add "$3") + touch -m -d "$expiry" $ZAF_CACHE_DIR/$key.info zaf_trc "Cache: Saving entry $1($key)" } @@ -37,13 +39,15 @@ zaf_tocache(){ zaf_tocache_stdin(){ ! [ -w $ZAF_CACHE_DIR ] && return 1 local key + local expiry 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 + expiry=$(zaf_date_add "$3") + touch -m -d "$expiry" $ZAF_CACHE_DIR/$key.info cat $ZAF_CACHE_DIR/$key else rm $ZAF_CACHE_DIR/$key diff --git a/lib/plugin.lib.sh b/lib/plugin.lib.sh new file mode 100644 index 0000000..112335e --- /dev/null +++ b/lib/plugin.lib.sh @@ -0,0 +1,259 @@ +# Plugin related functions + +# Update repo +zaf_update_repo() { + [ "$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_REPO_GITURL}" "${ZAF_REPO_DIR}" + (cd ${ZAF_REPO_DIR} && git pull) + fi +} + +# Construct url from plugin name +# It can be http[s]://url +# /path (from file) +# 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 + 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 + 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 + echo $url +} + +# $1 - control +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) + 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 + echo -n "Plugin '$plugin' "; [ -n "$pversion" ] && echo -n "version ${pversion}"; echo ":" + echo "$pdescription"; echo + [ -n "$pmaintainer" ] && echo "Maintainer: $pmaintainer" + [ -n "$purl" ] && echo "Url: $purl" + [ -n "$phome" ] && echo "Home: $phome" + 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 +} + +# Prepare plugin into dir +# $1 is url, directory or plugin name (will be searched in default plugin dir). +# $2 is directory to prepare. +zaf_prepare_plugin() { + 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" + zaf_dbg "Fetching control file from $url ..." + if zaf_fetch_url "$url" >"${control}"; then + zaf_ctrl_check_deps "${control}" + else + 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 + local version + + if zaf_prepare_plugin "$1" "${ZAF_TMP_DIR}/plugin"; then + url=$(zaf_get_plugin_url "$1") + control="${ZAF_TMP_DIR}/plugin/control.zaf" + plugin=$(zaf_ctrl_get_global_option $control Plugin) + version=$(zaf_ctrl_get_global_option $control Version) + plugindir="${ZAF_PLUGINS_DIR}"/$plugin + if [ -n "$plugin" ] && zaf_prepare_plugin "$1" $plugindir; then + zaf_wrn "Installing plugin $plugin version $version" + zaf_dbg "Source url: $url, Destination dir: $plugindir" + control=${plugindir}/control.zaf + [ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}" + zaf_ctrl_check_deps "${control}" + 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" + zaf_ctrl_install "$url" "${control}" "${plugindir}" + else + zaf_err "Cannot install plugin '$plugin' to $plugindir!" + fi + else + zaf_err "Cannot prepare plugin $1" + fi +} + +# List installed plugins +# $1 - plugin +zaf_list_plugins() { + local cfile + local plugin + 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 +} + +zaf_discovery_plugins() { + zaf_list_plugins | zaf_discovery '{#PLUGIN}' +} + +# $1 plugin +# $2 ctrl_option +zaf_plugin_option() { + local plugindir + local cfile + + if [ -z "$1" ]; then + zaf_err "Missing plugin name."; + fi + if zaf_is_plugin "$1"; then + plugindir="${ZAF_PLUGINS_DIR}/$1" + cfile="$plugindir/control.zaf" + zaf_ctrl_get_global_option $cfile $2 + else + 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. "; + fi + plugindir="${ZAF_PLUGINS_DIR}/$1" + cfile="$plugindir/control.zaf" + 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 + 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 + [ "$2" != "precache" ] && echo -n "$key " + done + echo +} + +zaf_list_items() { + for p in $(zaf_list_plugins); do + echo $p: $(zaf_list_plugin_items $p) + done +} + +zaf_get_item() { + if which zabbix_get >/dev/null; then + zaf_dbg zabbix_get -s localhost -k "'$1'" + (zabbix_get -s localhost -k "$1" | tr '\n' ' '; echo) || 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() { + if $ZAF_AGENT_BIN -t "$1" | grep ZBX_NOTSUPPORTED; then + return 1 + else + $ZAF_AGENT_BIN -t "$1" | tr '\n' ' ' + echo + fi +} + +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() { + ! zaf_is_plugin $1 && { zaf_err "Plugin $1 not installed!"; } + zaf_wrn "Removing plugin $1 (version $(zaf_plugin_version $1))" + rm -rf ${ZAF_PLUGINS_DIR}/$1 + rm -f ${ZAF_AGENT_CONFIGD}/zaf_$1.conf ${ZAF_CROND}/zaf_$1 ${ZAF_SUDOERSD}/zaf_$1 +} + diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index fc9322b..25eaca0 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -186,263 +186,6 @@ zaf_check_agent_config() { ${ZAF_AGENT_BIN} -t zaf.version } -# Update repo -zaf_update_repo() { - [ "$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_REPO_GITURL}" "${ZAF_REPO_DIR}" - (cd ${ZAF_REPO_DIR} && git pull) - fi -} - -# Construct url from plugin name -# It can be http[s]://url -# /path (from file) -# 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 - 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 - 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 - echo $url -} - -# $1 - control -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) - 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 - echo -n "Plugin '$plugin' "; [ -n "$pversion" ] && echo -n "version ${pversion}"; echo ":" - echo "$pdescription"; echo - [ -n "$pmaintainer" ] && echo "Maintainer: $pmaintainer" - [ -n "$purl" ] && echo "Url: $purl" - [ -n "$phome" ] && echo "Home: $phome" - 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 -} - -# Prepare plugin into dir -# $1 is url, directory or plugin name (will be searched in default plugin dir). -# $2 is directory to prepare. -zaf_prepare_plugin() { - 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" - zaf_dbg "Fetching control file from $url ..." - if zaf_fetch_url "$url" >"${control}"; then - zaf_ctrl_check_deps "${control}" - else - 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 - local version - - if zaf_prepare_plugin "$1" "${ZAF_TMP_DIR}/plugin"; then - url=$(zaf_get_plugin_url "$1") - control="${ZAF_TMP_DIR}/plugin/control.zaf" - plugin=$(zaf_ctrl_get_global_option $control Plugin) - version=$(zaf_ctrl_get_global_option $control Version) - plugindir="${ZAF_PLUGINS_DIR}"/$plugin - if [ -n "$plugin" ] && zaf_prepare_plugin "$1" $plugindir; then - zaf_wrn "Installing plugin $plugin version $version" - zaf_dbg "Source url: $url, Destination dir: $plugindir" - control=${plugindir}/control.zaf - [ "$ZAF_DEBUG" -gt 1 ] && zaf_plugin_info "${control}" - zaf_ctrl_check_deps "${control}" - 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" - zaf_ctrl_install "$url" "${control}" "${plugindir}" - else - zaf_err "Cannot install plugin '$plugin' to $plugindir!" - fi - else - zaf_err "Cannot prepare plugin $1" - fi -} - -# List installed plugins -# $1 - plugin -zaf_list_plugins() { - local cfile - local plugin - 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 -} - -zaf_discovery_plugins() { - zaf_list_plugins | zaf_discovery '{#PLUGIN}' -} - -# $1 plugin -# $2 ctrl_option -zaf_plugin_option() { - local plugindir - local cfile - - if [ -z "$1" ]; then - zaf_err "Missing plugin name."; - fi - if zaf_is_plugin "$1"; then - plugindir="${ZAF_PLUGINS_DIR}/$1" - cfile="$plugindir/control.zaf" - zaf_ctrl_get_global_option $cfile $2 - else - 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. "; - fi - plugindir="${ZAF_PLUGINS_DIR}/$1" - cfile="$plugindir/control.zaf" - 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 - 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 - [ "$2" != "precache" ] && echo -n "$key " - done - echo -} - -zaf_list_items() { - for p in $(zaf_list_plugins); do - echo $p: $(zaf_list_plugin_items $p) - done -} - -zaf_get_item() { - if which zabbix_get >/dev/null; then - zaf_dbg zabbix_get -s localhost -k "'$1'" - (zabbix_get -s localhost -k "$1" | tr '\n' ' '; echo) || 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() { - if $ZAF_AGENT_BIN -t "$1" | grep ZBX_NOTSUPPORTED; then - return 1 - else - $ZAF_AGENT_BIN -t "$1" | tr '\n' ' ' - echo - fi -} - -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() { - ! zaf_is_plugin $1 && { zaf_err "Plugin $1 not installed!"; } - zaf_wrn "Removing plugin $1 (version $(zaf_plugin_version $1))" - rm -rf ${ZAF_PLUGINS_DIR}/$1 - rm -f ${ZAF_AGENT_CONFIGD}/zaf_$1.conf ${ZAF_CROND}/zaf_$1 ${ZAF_SUDOERSD}/zaf_$1 -} - zaf_tolower() { tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' } @@ -469,3 +212,9 @@ zaf_strescape() { sed -e 's#\(['"$1"']\)#\\\1#g' } +# Add seconds to current date and return date in YYYY-MM-DD hh:mm:ss +# $1 seconds +zaf_date_add() { + date -d "$1 seconds" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -d "$(expr $(date +%s) + $1)" -D %s "+%Y-%m-%d %H:%M:%S" +} + diff --git a/lib/zbxapi.lib.sh b/lib/zbxapi.lib.sh index 50c013a..a867a6b 100644 --- a/lib/zbxapi.lib.sh +++ b/lib/zbxapi.lib.sh @@ -3,45 +3,52 @@ # $1 - query string zaf_zbxapi_do() { local result + local tmpfile + + tmpfile=$ZAF_TMP_DIR/zapi$$ 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 + curl -s -f -L -X POST -H 'Content-Type: application/json-rpc' -d "$1" "$ZAF_ZBXAPI_URL" >$tmpfile + if [ $? = 0 ] && $ZAF_LIB_DIR/JSON.sh -b <$tmpfile | grep -q '"result"'; then zaf_trc "API OK" - echo $result + cat $tmpfile + rm -f $tmpfile else - zaf_err "Error processing API request. ($?,$result)" + zaf_err "Error processing API request. ($?,$tmpfile)" fi } # Call api function and cache results # $1 - query string zaf_zbxapi_do_cache() { local result + local tmpfile + + tmpfile=$ZAF_TMP_DIR/zcapi$$ if ! zaf_fromcache "$1"; then - result=$(zaf_zbxapi_do "$1") - [ -n "$result" ] && zaf_tocache "$1" "$result" 60 - echo $result + zaf_zbxapi_do "$1" >$tmpfile + [ -s "$tmpfile" ] && cat $tmpfile | zaf_tocache_stdin "$1" 60 + rm -f $tmpfile fi } -# Extract result from JSON response +# Extract one result from JSON response zaf_zbxapi_getresult() { - sed -e 's/\({"jsonrpc":"2.0","result":\)\(.*\),\("id":.*\)/\2/g' | sed -e 's/^\[\]$//' + $ZAF_LIB_DIR/JSON.sh -b | grep '\["result"\]' | tr '\t' ' ' | cut -d ' ' -f 2- } # 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 '<">/' + zaf_zbxapi_getstring | zaf_strunescape '' | zaf_far '\\n' "\n" } # Extract string from JSON response result zaf_zbxapi_getstring() { - sed -e 's/^"//' -e 's/"$//' -e 's/\\n/'\\n'/g' + zaf_zbxapi_getresult | sed -e 's/^"//' -e 's/"$//' } # Extract value from JSON response result # $1 key -zaf_zbxapi_getvalue() { - tr ',' '\n' | grep "\"$1\":" | cut -d '"' -f 4 +zaf_zbxapi_getvalues() { + $ZAF_LIB_DIR/JSON.sh -b | grep '\["result",.*,"'$1'"]' | tr '\t' ' ' | cut -d ' ' -f 2- | sed -e 's/^"//' -e 's/"$//' } # Zabbix API related functions @@ -68,7 +75,7 @@ zaf_zbxapi_login(){ 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) + ZAF_ZBXAPI_AUTH=$(echo $result |zaf_zbxapi_getstring) [ -z "$ZAF_ZBXAPI_AUTH" ] && zaf_err "Cannot login into API" zaf_dbg "Logged into zabbix API ($ZAF_ZBXAPI_AUTH)" } @@ -102,7 +109,7 @@ zaf_zbxapi_get_object() { params='"params": {'$filter' "output":"'$output'"}'; fi str='{ "method": "'$obj'.get", "jsonrpc": "2.0", "auth": "'$ZAF_ZBXAPI_AUTH'",'$params', "id": "'$id'" }' - result=$(zaf_zbxapi_do_cache "$str" | zaf_zbxapi_getresult) + result=$(zaf_zbxapi_do_cache "$str") [ -z "$result" ] && zaf_dbg "API call result empty or error! ($str)" echo $result } @@ -113,7 +120,7 @@ zaf_zbxapi_gethostgroupid() { result=$(zaf_zbxapi_get_object "hostgroup" '"name": ["'$1'"]') [ -z "$result" ] && zaf_err "HostGroup $1 not found!" - echo $result |zaf_zbxapi_getvalue groupid + echo $result |zaf_zbxapi_getvalues groupid } # $1 hostid @@ -126,7 +133,7 @@ zaf_zbxapi_gethost() { if [ -z "$2" ]; then echo $result else - echo $result |zaf_zbxapi_getvalue $2 + echo $result |zaf_zbxapi_getvalues $2 fi } @@ -136,7 +143,7 @@ zaf_zbxapi_gethostid() { result=$(zaf_zbxapi_get_object "host" '"host": ["'$1'"]') [ -z "$result" ] && zaf_err "Host $1 not found!" - echo $result |zaf_zbxapi_getvalue hostid + echo $result |zaf_zbxapi_getvalues hostid } # $1 hostname @@ -149,7 +156,7 @@ zaf_zbxapi_gethostinventory() { if [ -z "$2" ]; then echo $result else - echo $result |zaf_zbxapi_getvalue $2 + echo $result |zaf_zbxapi_getvalues $2 fi } @@ -159,7 +166,7 @@ zaf_zbxapi_gettemplateid() { result=$(zaf_zbxapi_get_object "template" '"host": ["'$1'"]') [ -z "$result" ] && zaf_err "Template $1 not found!" - echo $result |zaf_zbxapi_getvalue templateid + echo $result |zaf_zbxapi_getvalues templateid } # $1 templateid @@ -172,7 +179,7 @@ zaf_zbxapi_gettemplate() { if [ -z "$2" ]; then echo $result else - echo $result |zaf_zbxapi_getvalue $2 + echo $result |zaf_zbxapi_getvalues $2 fi } @@ -182,7 +189,7 @@ zaf_zbxapi_gethostsingroup() { result=$(zaf_zbxapi_get_object "host" '' '"groupids": ["'$1'"]') [ -z "$result" ] && zaf_wrn "No hosts in groupid '$1'" - echo $result | zaf_zbxapi_getvalue "hostid" + echo $result | zaf_zbxapi_getvalues "hostid" } # Get all hostids in system @@ -190,7 +197,7 @@ zaf_zbxapi_gethostids() { local result result=$(zaf_zbxapi_get_object "host") - echo $result | zaf_zbxapi_getvalue "hostid" + echo $result | zaf_zbxapi_getvalues "hostid" } # Get all templateids in system @@ -198,7 +205,7 @@ zaf_zbxapi_gettemplateids() { local result result=$(zaf_zbxapi_get_object "template") - echo $result | zaf_zbxapi_getvalue "templateid" + echo $result | zaf_zbxapi_getvalues "templateid" } # $1 hostgroupid @@ -207,7 +214,7 @@ zaf_zbxapi_gettemplatesingroup() { result=$(zaf_zbxapi_get_object "template" '' '"groupids": ["'$1'"]') [ -z "$result" ] && zaf_wrn "No templates in groupid '$1'" - echo $result | zaf_zbxapi_getvalue "templateid" + echo $result | zaf_zbxapi_getvalues "templateid" } # $1 map or null for all @@ -220,7 +227,7 @@ zaf_zbxapi_getmapid() { result=$(zaf_zbxapi_get_object "map") fi [ -z "$result" ] && zaf_err "Map $1 not found" - echo $result | zaf_zbxapi_getvalue "sysmapid" + echo $result | zaf_zbxapi_getvalues "sysmapid" } # $1 mapid @@ -233,7 +240,7 @@ zaf_zbxapi_getmap() { if [ -z "$2" ]; then echo $result else - echo $result |zaf_zbxapi_getvalue $2 + echo $result |zaf_zbxapi_getvalues $2 fi } diff --git a/zaf b/zaf index ce22d1e..c78211e 100755 --- a/zaf +++ b/zaf @@ -44,6 +44,7 @@ fi if [ -f ./lib/zaf.lib.sh ]; then . ./lib/zaf.lib.sh +. ./lib/plugin.lib.sh . ./lib/os.lib.sh . ./lib/ctrl.lib.sh . ./lib/cache.lib.sh @@ -397,7 +398,10 @@ api) zaf_hlp "get-${i}-id $i" "Get $i id" zaf_hlp "get-byid-${i} id [property]" "Get $i property from id. Leave empty property for JSON" done - zaf_hlp "get-inventory host [fields]" "Get inventory fields [or all fields]" + zaf_hlp "get-inventory host [fields]" "Get inventory fields [or all fields]" + zaf_hlp "get-host-ids [hg]" "Get all hostids or hostids in group hg" + zaf_hlp "get-template-ids [hg]" "Get all templateids or templateids in group hg" + zaf_hlp "get-map-ids" "Get all mapids" zaf_hlp "export-hosts dir [hg]" "Backup all hosts [in group hg] (get their config from zabbix and save to dir/hostname.xml)" zaf_hlp "export-host host" "Backup host (get config from zabbix to stdout)" zaf_hlp "import-template {plugin|file}" "Import template for plugin or from file" From ca3962ba05a0ab3d1f148c3e25e96b6cb1be64b7 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 15:59:45 +0200 Subject: [PATCH 13/32] cache-clean sets right permissions --- lib/cache.lib.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 8ae1378..80a6036 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -8,6 +8,10 @@ zaf_cache_clean(){ zaf_err "Cache dir not set." fi mkdir -p "$ZAF_CACHE_DIR" + if zaf_is_root; then + chmod g+rwx "$ZAF_CACHE_DIR" + chgrp zabbix "$ZAF_CACHE_DIR" + fi } # Get cache key from requested param From 14d78f1b15714f8a02ade410308d5045d5a6ed68 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 17:38:02 +0200 Subject: [PATCH 14/32] Missed include file --- zaf | 1 + 1 file changed, 1 insertion(+) diff --git a/zaf b/zaf index c78211e..b0eb4a1 100755 --- a/zaf +++ b/zaf @@ -52,6 +52,7 @@ if [ -f ./lib/zaf.lib.sh ]; then [ -f ./lib/zaf.${ZAF_OS}.sh ] && . ./lib/zaf.${ZAF_OS}.sh else . ${ZAF_LIB_DIR}/zaf.lib.sh +. ${ZAF_LIB_DIR}/plugin.lib.sh . ${ZAF_LIB_DIR}/os.lib.sh . ${ZAF_LIB_DIR}/ctrl.lib.sh . ${ZAF_LIB_DIR}/cache.lib.sh From c0b57ea7bef1a49909cdc2ffe8804a224a915654 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Tue, 19 Apr 2016 20:11:09 +0200 Subject: [PATCH 15/32] Repaired function name --- zaf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zaf b/zaf index b0eb4a1..75027f3 100755 --- a/zaf +++ b/zaf @@ -374,20 +374,20 @@ api) if [ -f "$ZAF_PLUGINS_DIR/$1/template.xml" ]; then template="$ZAF_PLUGINS_DIR/$1/template.xml" zaf_wrn "Importing template $template" - zaf_zbxapi_import_template $template || zaf_err "Error importing template" + zaf_zbxapi_import_config $template || zaf_err "Error importing template" else url="$(zaf_plugin_option $1 Template)" if [ -n "$url" ]; then - zaf_fetch_url $url | zaf_zbxapi_import_template || zaf_err "Error importing template" + zaf_fetch_url $url | zaf_zbxapi_import_config || zaf_err "Error importing template" else url="$(zaf_plugin_option $1 Url)" - zaf_fetch_url $url/template.xml | zaf_zbxapi_import_template || zaf_err "Error importing template" + zaf_fetch_url $url/template.xml | zaf_zbxapi_import_config || zaf_err "Error importing template" fi fi else if [ -f $1 ]; then zaf_wrn "Importing template $1" - zaf_zbxapi_import_template $1 || zaf_err "Error importing template" + zaf_zbxapi_import_config $1 || zaf_err "Error importing template" else zaf_err "Unknown plugin $1!" fi From 76352d7d12c823cb160dbe3c7b3f5e32c184abb3 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Wed, 20 Apr 2016 09:39:24 +0200 Subject: [PATCH 16/32] Repaired touch variants Added cache-list command --- lib/cache.lib.sh | 26 ++++++++++++++++++-------- lib/os.lib.sh | 1 + lib/zaf.lib.sh | 7 ------- lib/zbxapi.lib.sh | 10 +++++++--- zaf | 7 ++++--- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 80a6036..0cc3285 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -16,7 +16,7 @@ zaf_cache_clean(){ # Get cache key from requested param zaf_cache_key(){ - echo "$1" | md5sum - | cut -d ' ' -f 1 + echo "$1" | (md5sum - ||md5) 2>/dev/null | cut -d ' ' -f 1 } # Put object into cache @@ -31,10 +31,10 @@ zaf_tocache(){ key=$(zaf_cache_key "$1") echo "$2" >$ZAF_CACHE_DIR/$key - echo "$1" >$ZAF_CACHE_DIR/$key.info + echo "$1" >$ZAF_CACHE_DIR/${key}.info expiry=$(zaf_date_add "$3") - touch -m -d "$expiry" $ZAF_CACHE_DIR/$key.info - zaf_trc "Cache: Saving entry $1($key)" + zaf_trc "Cache: Saving entry $1[$key,expiry=$expiry]" + touch -m -d "$expiry" $ZAF_CACHE_DIR/${key}.info } # Put object into cache from stdin and copy to stdout @@ -48,13 +48,13 @@ zaf_tocache_stdin(){ 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 - expiry=$(zaf_date_add "$3") + expiry="$(zaf_date_add $2)" + echo "$1 [key=$key,expiry=$expiry]" >$ZAF_CACHE_DIR/${key}.info + zaf_trc "Cache: Saving entry $1[key=$key,expiry=$expiry]" touch -m -d "$expiry" $ZAF_CACHE_DIR/$key.info cat $ZAF_CACHE_DIR/$key else - rm $ZAF_CACHE_DIR/$key + rm -f "$ZAF_CACHE_DIR/$key" fi } @@ -68,6 +68,16 @@ zaf_cache_delentry(){ rm -f "$ZAF_CACHE_DIR/$key*" } +# List entries in cache +zaf_cache_list(){ + local i + ls $ZAF_CACHE_DIR/*info >/dev/null 2>/dev/null || return 1 + local key + for i in $ZAF_CACHE_DIR/*info; do + cat $i + done +} + # Get object from cache # $1 key zaf_fromcache(){ diff --git a/lib/os.lib.sh b/lib/os.lib.sh index 744396a..d10ed66 100644 --- a/lib/os.lib.sh +++ b/lib/os.lib.sh @@ -17,6 +17,7 @@ zaf_configure_os_freebsd() { 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_SUDOERSD="/usr/local/etc/sudoers.d" } zaf_detect_system() { diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 25eaca0..1856134 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -180,12 +180,6 @@ zaf_restart_agent() { ${ZAF_AGENT_RESTART} || zaf_err "Cannot restart Zabbix agent (${ZAF_AGENT_RESTART}). Try $ZAF_AGENT_BIN -f !"; } -# Check if zaf.version item is populated -zaf_check_agent_config() { - zaf_restart_agent - ${ZAF_AGENT_BIN} -t zaf.version -} - zaf_tolower() { tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' } @@ -205,7 +199,6 @@ zaf_strunescape() { sed -e 's#\\\(['"$1"']\)#\1#g' } - # Escape string on stdin # $1 - list of chars to escape zaf_strescape() { diff --git a/lib/zbxapi.lib.sh b/lib/zbxapi.lib.sh index a867a6b..7bbe4e4 100644 --- a/lib/zbxapi.lib.sh +++ b/lib/zbxapi.lib.sh @@ -3,11 +3,13 @@ # $1 - query string zaf_zbxapi_do() { local result + local query local tmpfile tmpfile=$ZAF_TMP_DIR/zapi$$ - zaf_trc "Zabbix API: $1" - curl -s -f -L -X POST -H 'Content-Type: application/json-rpc' -d "$1" "$ZAF_ZBXAPI_URL" >$tmpfile + query="$1" + zaf_trc "Zabbix API: $query" + curl -s -f -L -X POST -H 'Content-Type: application/json-rpc' -d "$query" "$ZAF_ZBXAPI_URL" >$tmpfile if [ $? = 0 ] && $ZAF_LIB_DIR/JSON.sh -b <$tmpfile | grep -q '"result"'; then zaf_trc "API OK" cat $tmpfile @@ -21,11 +23,13 @@ zaf_zbxapi_do() { zaf_zbxapi_do_cache() { local result local tmpfile + local query + query="$(echo $1 | tr '\n' ' ')" tmpfile=$ZAF_TMP_DIR/zcapi$$ if ! zaf_fromcache "$1"; then zaf_zbxapi_do "$1" >$tmpfile - [ -s "$tmpfile" ] && cat $tmpfile | zaf_tocache_stdin "$1" 60 + [ -s "$tmpfile" ] && cat $tmpfile | zaf_tocache_stdin "$query" 60 rm -f $tmpfile fi } diff --git a/zaf b/zaf index c78211e..18383d8 100755 --- a/zaf +++ b/zaf @@ -69,6 +69,9 @@ case $1 in cache-clean) zaf_cache_clean ;; +cache-list) + zaf_cache_list + ;; version) echo "$ZAF_VERSION" @@ -95,9 +98,6 @@ agent-config) | zaf_far '{PLUGINDIR}' "${plugindir}" >${ZAF_AGENT_CONFIGD}/zaf_${plugin}.conf done ;; -check-agent-config) - zaf_check_agent_config - ;; ###### Plugins related commands update) @@ -443,6 +443,7 @@ api) zaf_hlp "$0 self-upgrade" "To self-upgrade zaf" zaf_hlp "$0 self-remove" "To self-remove zaf and its config" zaf_hlp "$0 cache-clean" "To remove all entries from cache" + zaf_hlp "$0 cache-list" "To show all entries in cache" echo [ -n "$1" ] && zaf_err "Bad command '$1'!" ;; From 957c53958c020b3dd6c3607e4019f4e8ffb628c1 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 21 Apr 2016 15:29:48 +0200 Subject: [PATCH 17/32] New syntax and tests --- install.sh | 40 ++++++++++++++++++++------------- lib/cache.lib.sh | 3 ++- lib/ctrl.lib.sh | 28 +++++++++++++++-------- lib/plugin.lib.sh | 27 +++++++++++++++++++++- lib/preload.sh | 41 +++++++++++++++++++++++++--------- lib/zaf.lib.sh | 46 +++++++++++++++++++++++++++++++++----- lib/zafcache | 23 ++++++++++++++++--- lib/zaflock | 7 +++--- zaf | 57 ++++++++++++++++++++++++++--------------------- 9 files changed, 198 insertions(+), 74 deletions(-) diff --git a/install.sh b/install.sh index b86a913..0e74e80 100755 --- a/install.sh +++ b/install.sh @@ -1,6 +1,7 @@ #!/bin/sh [ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 +export ZAF_LOG_STDERR="-s" if [ -z "$ZAF_URL" ]; then # Runing as standalone install.sh. We have to download rest of files first. ZAF_URL="https://github.com/limosek/zaf/" @@ -8,20 +9,28 @@ fi [ -z "$ZAF_GITBRANCH" ] && ZAF_GITBRANCH=1.2 +ZAF_TMP_DIR="/tmp/zaf-installer" +ZAF_DIR="$ZAF_TMP_DIR/zaf" + # Lite version of zaf_fetch_url, full version will be loaded later zaf_fetch_url(){ - if [ -z "$ZAF_OFFLINE" ]; then - echo curl -f -k -s -L -o - "$1" >&2; curl -f -k -s -L -o - "$1" - else - echo "Offline mode wants to download $1. Exiting." >&2 - exit 2 - fi + echo curl -f -k -s -L -o - "$1" >&2; + curl -f -k -s -L -o - "$1" } -# Download tgz and extract to /tmp/zaf-installer +# Lite version of zaf_err, full version will be loaded later +zaf_err() { + logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error -- $@ + logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error "Exiting with error!" + exit 1 +} + +# Download tgz and extract to tmpdir zaf_download_files() { - rm -rf /tmp/zaf-installer - zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C /tmp -zx && mv /tmp/zaf-$ZAF_GITBRANCH /tmp/zaf-installer + [ -n $ZAF_DIR ] && zaf_err "ZAF_DIR not set!" + rm -rf $ZAF_DIR + zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C $ZAF_TMP_DIR -zx && mv $ZAF_TMP_DIR/zaf-$ZAF_GITBRANCH $ZAF_DIR \ + || zaf_err "Cannot download and unpack zaf!" } if ! [ -f README.md ]; then @@ -32,7 +41,7 @@ if ! [ -f README.md ]; then fi echo "Installing from url $url..." [ -z "$*" ] && auto=auto - zaf_download_files && cd /tmp/zaf-installer && exec ./install.sh $auto "$@" + zaf_download_files && cd $ZAF_DIR && exec ./install.sh $auto "$@" echo "Error downloading and runing installer!" >&2 exit 2 fi @@ -276,7 +285,7 @@ zaf_configure(){ } zaf_install_all() { - rm -rif ${ZAF_TMP_DIR} + rm -rf ${ZAF_TMP_DIR} mkdir -p ${ZAF_TMP_DIR} zaf_install_dir ${ZAF_LIB_DIR} for i in lib/zaf.lib.sh lib/plugin.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh lib/JSON.sh README.md; do @@ -317,14 +326,15 @@ zaf_postconfigure() { if [ -f "${ZAF_CFG_FILE}" ]; then . "${ZAF_CFG_FILE}" fi -ZAF_TMP_DIR="/tmp/zaf-installer-tmp/" +ZAF_TMP_DIR="/tmp/zaf-installer/" +! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" # If debug is on, do not remove tmp dir if [ "$ZAF_DEBUG" -le 3 ]; then - trap "rm -rif ${ZAF_TMP_DIR}" EXIT - trap "rm -rif /tmp/zaf-installer" EXIT + trap "rm -rf ${ZAF_TMP_DIR} " EXIT +else + trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT fi -! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" case $1 in interactive) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 0cc3285..9a7c985 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -9,7 +9,7 @@ zaf_cache_clean(){ fi mkdir -p "$ZAF_CACHE_DIR" if zaf_is_root; then - chmod g+rwx "$ZAF_CACHE_DIR" + chmod 770 "$ZAF_CACHE_DIR" chgrp zabbix "$ZAF_CACHE_DIR" fi } @@ -86,6 +86,7 @@ zaf_fromcache(){ local value key=$(zaf_cache_key "$1") if [ -f $ZAF_CACHE_DIR/$key ]; then + ! [ -f "$ZAF_CACHE_DIR/$key.info" ] && { return 3; } 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 diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 275bd20..3790e8e 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -191,20 +191,28 @@ zaf_ctrl_generate_cfg() { local ikey local lock local cache + local tmpfile + local pname + local pdefault + local pregex + local prest + local zafparms items=$(zaf_ctrl_get_items <"$1") + tmpfile=$ZAF_TMP_DIR/gencfg$$ (set -e for i in $items; do iscript=$(zaf_stripctrl $i) - params=$(zaf_ctrl_get_item_option $1 $i "Parameters") - if [ -n "$params" ]; then + zaf_ctrl_get_item_option $1 $i "Parameters" >$tmpfile + if [ -s "$tmpfile" ]; then ikey="$2.$i[*]" args="" apos=1; - for p in $params; do + while read pname pdefault pregex prest; do + zafparams="$zafparams value=\"\$$apos\"; zaf_agentparm $pname $pdefault $pregex;" args="$args \$$apos" apos=$(expr $apos + 1) - done + done <$tmpfile else ikey="$2.$i" fi @@ -223,16 +231,18 @@ zaf_ctrl_generate_cfg() { preload="" fi if [ -n "$cmd" ]; then - printf "%s" "UserParameter=$ikey,${preload}${cache}${lock}${cmd}"; echo + printf "%s" "UserParameter=$ikey,export ITEM_KEY='$ikey'; ${preload}${cache}${lock}${cmd}"; echo continue fi cmd=$(zaf_ctrl_get_item_option $1 $i "Script") if [ -n "$cmd" ]; then - zaf_ctrl_get_item_option $1 $i "Script" | \ - zaf_far '{INCLUDES}' ". $ZAF_LIB_DIR/preload.sh; " \ - >${ZAF_TMP_DIR}/${iscript}.sh; + ( echo "#!/bin/sh" + echo ". $ZAF_LIB_DIR/preload.sh; " + echo "$zafparams" + zaf_ctrl_get_item_option $1 $i "Script" + ) >${ZAF_TMP_DIR}/${iscript}.sh; [ -z "$3" ] && zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ - printf "%s" "UserParameter=$ikey,${preload}${cache}${lock}${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args"; echo + printf "%s" "UserParameter=$ikey,export ITEM_KEY='$ikey'; ${preload}${cache}${lock}${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args"; echo continue; fi zaf_err "Item $i declared in control file but has no Cmd, Function or Script!" diff --git a/lib/plugin.lib.sh b/lib/plugin.lib.sh index 112335e..90ad655 100644 --- a/lib/plugin.lib.sh +++ b/lib/plugin.lib.sh @@ -218,6 +218,30 @@ zaf_list_plugin_items() { echo } +zaf_item_info() { + local plugin + local item + + plugin=$(echo $1 | cut -d '.' -f 1) + item=$(echo $1 | cut -d '.' -f 2-) + if zaf_is_plugin $plugin; then + if zaf_ctrl_get_items <$ZAF_PLUGINS_DIR/$plugin/control.zaf | grep -wq "$item"; then + echo "Item $1:" + echo -n "Cache: "; zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Cache"; echo + echo "Parameters:" + zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Parameters" ; echo + echo "Testparameters:" + zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Testparameters" ; echo + echo "Precache:" + zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Precache" ; echo + else + zaf_err "No such item $item." + fi + else + zaf_err "No such plugin $plugin." + fi +} + zaf_list_items() { for p in $(zaf_list_plugins); do echo $p: $(zaf_list_plugin_items $p) @@ -226,7 +250,7 @@ zaf_list_items() { zaf_get_item() { if which zabbix_get >/dev/null; then - zaf_dbg zabbix_get -s localhost -k "'$1'" + zaf_trc zabbix_get -s localhost -k "'$1'" (zabbix_get -s localhost -k "$1" | tr '\n' ' '; echo) || zaf_wrn "Cannot reach agent on localhost. Please localhost to Server list." return 11 else @@ -236,6 +260,7 @@ zaf_get_item() { } zaf_test_item() { + zaf_trc $ZAF_AGENT_BIN -t "'$1'" if $ZAF_AGENT_BIN -t "$1" | grep ZBX_NOTSUPPORTED; then return 1 else diff --git a/lib/preload.sh b/lib/preload.sh index ec182cf..d638215 100644 --- a/lib/preload.sh +++ b/lib/preload.sh @@ -2,27 +2,46 @@ . /etc/zaf.conf -[ -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}/plugin.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 +[ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf +[ -z "$ZAF_TMP_DIR" ] && ZAF_TMP_DIR="${ZAF_TMP_BASE}-$(zaf_random)" +[ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c + +rm -rf "${ZAF_TMP_DIR}" + +if ! [ -d "${ZAF_TMP_DIR}" ]; then + mkdir "${ZAF_TMP_DIR}" +fi + +! [ -d "${ZAF_CACHE_DIR}" ] && mkdir "${ZAF_CACHE_DIR}" +[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 + +if [ "$ZAF_DEBUG" -le 3 ]; then + trap "rm -rf ${ZAF_TMP_DIR}" EXIT +else + trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT +fi + +#trap 'touch /tmp/aaaa' ALARM + export ZAF_LIB_DIR export ZAF_TMP_DIR export ZAF_CACHE_DIR export ZAF_PLUGINS_DIR +export ZAF_DEBUG +unset ZAF_LOG_STDERR +export PATH=$ZAF_LIB_DIR:$ZAF_BIN_DIR:$PATH -[ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ] && $@ - +if [ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ]; then + tmpf=$(zaf_tmpfile preload) + $@ 2>$tmpf + [ -s $tmpf ] && zaf_wrn <$tmpf +fi diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 1856134..19566db 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -11,17 +11,17 @@ zaf_msg() { echo $@ } zaf_trc() { - [ "$ZAF_DEBUG" -ge "3" ] && logger -p user.info -s -t zaf-trace -- $@ + [ "$ZAF_DEBUG" -ge "3" ] && logger -p user.info ${ZAF_LOG_STDERR} -t zaf-trace -- $@ } zaf_dbg() { - [ "$ZAF_DEBUG" -ge "2" ] && logger -p user.debug -s -t zaf-debug -- $@ + [ "$ZAF_DEBUG" -ge "2" ] && logger -p user.debug ${ZAF_LOG_STDERR} -t zaf-debug -- $@ } zaf_wrn() { - [ "$ZAF_DEBUG" -ge "1" ] && logger -p user.warn -s -t zaf-warning -- $@ + [ "$ZAF_DEBUG" -ge "1" ] && logger -p user.warn ${ZAF_LOG_STDERR} -t zaf-warning -- $@ } zaf_err() { - logger -s -p user.err -t zaf-error -- $@ - logger -s -p user.err -t zaf-error "Exiting with error!" + logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error -- $@ + logger ${ZAF_LOG_STDERR} -p user.err -t zaf-error "Exiting with error!" exit 1 } # Help option @@ -43,6 +43,31 @@ zaf_version(){ echo $ZAF_VERSION } +# Add parameter for agent check +# $1 parameter name (will be set to var) +# $2 if nonempty, it is default value. If empty, parameter is mandatory +# $3 if nonempty, regexp to test +zaf_agentparm(){ + local name + local default + local regexp + + name="$1" + default="$2" + regexp="$3" + + [ -z "$value" ] && [ -z "$default" ] && zaf_err "$ITEM_KEY: Missing mandatory parameter $name." + if [ -z "$value" ]; then + value="$default" + else + if [ -n "$regexp" ]; then + echo "$value" | grep -qE "$regexp" || zaf_err "$ITEM_KEY: Bad parameter '$name' value '$value' (not in regexp '$regexp')." + fi + fi + eval $name=$value + zaf_trc "$ITEM_KEY: Param $name set to $value" +} + # Fetch url to stdout # $1 url # It supports real file, file:// and other schemes known by curl @@ -211,3 +236,14 @@ zaf_date_add() { date -d "$1 seconds" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -d "$(expr $(date +%s) + $1)" -D %s "+%Y-%m-%d %H:%M:%S" } +# Create temp file and return its name +# $1 prefix or empty +zaf_tmpfile() { + echo "$ZAF_TMP_DIR/tmp$1" +} + +# return random number +zaf_random() { + hexdump -n 2 -e '/2 "%u"' /dev/urandom +} + diff --git a/lib/zafcache b/lib/zafcache index 0a98c2d..3fc3c24 100644 --- a/lib/zafcache +++ b/lib/zafcache @@ -10,8 +10,25 @@ seconds=$1 shift [ -z "$*" ] && help -parms=$(echo $*|tr -d ' ') -if ! zaf_fromcache "$parms"; then - $@ | zaf_tocache_stdin "$parms" "$seconds" +zaf_trc "zafcache($seconds): $ITEM_KEY,'$2' '$3' '$4' '$5' '$6' '$7' '$8' '$9'" + +if [ -z "$ITEM_KEY" ]; then + key=$(echo $*|tr ' ' '_') +else + key="$(echo ${ITEM_KEY}|cut -d '[' -f 1)[$(shift; echo $*|tr ' ' ',')]" +fi + +if ! zaf_fromcache "$key"; then + zaf_fromcache "$key" >/dev/null 2>/dev/null + [ $? -eq 3 ] && { zaf_err "Operation $key already in progress."; } + if which at >/dev/null 2>/dev/null; then + at -M now >/dev/null 2>/dev/null <"\$tmpf" | zaf_tocache_stdin "$key" "$seconds" ; [ -s \$tmpf ] && zaf_wrn <\$tmpf +EOF + else + tmpf=$(zaf_tmpfile cache) + $@ 2>"$tmpf" | zaf_tocache_stdin "$key" "$seconds" + [ -s $tmpf ] && zaf_wrn <$tmpf + fi fi diff --git a/lib/zaflock b/lib/zaflock index a983f94..04d3575 100644 --- a/lib/zaflock +++ b/lib/zaflock @@ -13,7 +13,7 @@ shift [ -z "${ZAF_LOCK_SECONDS}" ] && seconds=5 [ -z "${ZAF_LOCK_FORCE}" ] && force=1 -lockfile="${ZAF_TMP_DIR}/zaflock_${lkey}" +lockfile="/tmp/zaflock_${lkey}" i=0 while [ -f "$lockfile" ] && [ $i -lt $seconds ]; do sleep 1 @@ -28,7 +28,6 @@ if [ -f "$lockfile" ] && [ -z "$force" ]; then exit 1 fi -touch "$lockfile" -[ -n "$*" ] && $@ -rm -f "$lockfile" +[ -n "$*" ] && $@ 2>"$lockfile" +[ -s "$lockfile" ] && zaf_wrn <"$lockfile" diff --git a/zaf b/zaf index e1cb691..350a56a 100755 --- a/zaf +++ b/zaf @@ -25,23 +25,6 @@ ZAF_CFG_FILE="/etc/zaf.conf" [ -n "$secondstage" ] && exec $0 $params fi -[ -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 - -[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 -export ZAF_DEBUG - -# If debug is on, do not remove tmp dir -if [ "$ZAF_DEBUG" -le 3 ]; then - trap "rm -rif ${ZAF_TMP_DIR}" EXIT -fi - -! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" -if ! [ -d "${ZAF_CACHE_DIR}" ]; then - mkdir "${ZAF_CACHE_DIR}" -fi - if [ -f ./lib/zaf.lib.sh ]; then . ./lib/zaf.lib.sh . ./lib/plugin.lib.sh @@ -60,6 +43,26 @@ else [ -f ${ZAF_LIB_DIR}/zaf.${ZAF_OS}.sh ] && . ${ZAF_LIB_DIR}/zaf.${ZAF_OS}.sh fi +[ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf +ZAF_TMP_DIR="${ZAF_TMP_BASE}-$(zaf_random)" +[ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c + +[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 +export ZAF_DEBUG +export ZAF_LOG_STDERR="-s" + +# If debug is on, do not remove tmp dir +if [ "$ZAF_DEBUG" -le 3 ]; then + trap "rm -rf ${ZAF_TMP_DIR}" EXIT +else + trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT +fi + +! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" +if ! [ -d "${ZAF_CACHE_DIR}" ]; then + mkdir "${ZAF_CACHE_DIR}" +fi + if zaf_is_root; then chgrp zabbix "${ZAF_CACHE_DIR}" chmod g+w "${ZAF_CACHE_DIR}" @@ -115,15 +118,19 @@ show) zaf_plugin_info $ZAF_PLUGINS_DIR/$plugin/control.zaf done else - if zaf_list_plugins | grep -q "^$1"; then - [ -f $ZAF_PLUGINS_DIR/$1/control.zaf ] && zaf_plugin_info $ZAF_PLUGINS_DIR/$1/control.zaf || zaf_err "Plugin $1 not installed." - else - if echo $1 |grep -q ^http; then - zaf_prepare_plugin "$1" "$ZAF_TMP_DIR/plugin" - zaf_plugin_info "$ZAF_TMP_DIR/plugin/control.zaf" + if echo $1 | grep -vq "\."; then + if zaf_list_plugins | grep -q "^$1"; then + zaf_is_plugin $1 && zaf_plugin_info $ZAF_PLUGINS_DIR/$1/control.zaf || zaf_err "Plugin $1 not installed." else - zaf_err "Plugin $1 not installed." + if echo $1 |grep -q ^http; then + zaf_prepare_plugin "$1" "$ZAF_TMP_DIR/plugin" + zaf_plugin_info "$ZAF_TMP_DIR/plugin/control.zaf" + else + zaf_err "Plugin $1 not installed." + fi fi + else + zaf_item_info "$1" fi fi ;; @@ -153,7 +160,7 @@ test) for p in $plugins; do ! zaf_is_plugin $p && zaf_err "Unknown plugin $p" for i in $(zaf_list_plugin_items $p test); do - echo $i: $(zaf_test_item $i) + zaf_test_item $i echo done done From b017f0d982a2bec26479611158db518900d76a15 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 21 Apr 2016 15:33:27 +0200 Subject: [PATCH 18/32] REpaired typo --- install.sh | 2 +- zaf | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 0e74e80..f13e2cc 100755 --- a/install.sh +++ b/install.sh @@ -27,7 +27,7 @@ zaf_err() { # Download tgz and extract to tmpdir zaf_download_files() { - [ -n $ZAF_DIR ] && zaf_err "ZAF_DIR not set!" + [ -z $ZAF_DIR ] && zaf_err "ZAF_DIR not set!" rm -rf $ZAF_DIR zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C $ZAF_TMP_DIR -zx && mv $ZAF_TMP_DIR/zaf-$ZAF_GITBRANCH $ZAF_DIR \ || zaf_err "Cannot download and unpack zaf!" diff --git a/zaf b/zaf index 350a56a..d8745f3 100755 --- a/zaf +++ b/zaf @@ -242,7 +242,6 @@ self-upgrade) shift [ -z "$1" ] && auto=auto zaf_os_specific zaf_check_deps zaf && zaf_err "Zaf is installed as system package. Cannot self-upgrade." - rm -rf /tmp/zaf-installer && mkdir /tmp/zaf-installer if ! which curl >/dev/null; then zaf_err "Curl not found. Cannot continue. Please install it." From 185438225c8523a6168135f2a3e5659f827cfd40 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 21 Apr 2016 15:44:39 +0200 Subject: [PATCH 19/32] Install changes --- install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index f13e2cc..cbe83e6 100755 --- a/install.sh +++ b/install.sh @@ -11,6 +11,7 @@ fi ZAF_TMP_DIR="/tmp/zaf-installer" ZAF_DIR="$ZAF_TMP_DIR/zaf" +mkdir -p $ZAF_TMP_DIR # Lite version of zaf_fetch_url, full version will be loaded later zaf_fetch_url(){ @@ -29,8 +30,7 @@ zaf_err() { zaf_download_files() { [ -z $ZAF_DIR ] && zaf_err "ZAF_DIR not set!" rm -rf $ZAF_DIR - zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C $ZAF_TMP_DIR -zx && mv $ZAF_TMP_DIR/zaf-$ZAF_GITBRANCH $ZAF_DIR \ - || zaf_err "Cannot download and unpack zaf!" + zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C $ZAF_TMP_DIR -zx && mv $ZAF_TMP_DIR/zaf-$ZAF_GITBRANCH $ZAF_DIR || zaf_err "Cannot download and unpack zaf!" } if ! [ -f README.md ]; then From c96a7a17dc8d62244ffcbf1ad943350d490d2252 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 21 Apr 2016 15:50:48 +0200 Subject: [PATCH 20/32] Rm deleted content before install --- install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/install.sh b/install.sh index cbe83e6..8ac9725 100755 --- a/install.sh +++ b/install.sh @@ -285,8 +285,6 @@ zaf_configure(){ } zaf_install_all() { - rm -rf ${ZAF_TMP_DIR} - mkdir -p ${ZAF_TMP_DIR} zaf_install_dir ${ZAF_LIB_DIR} for i in lib/zaf.lib.sh lib/plugin.lib.sh lib/os.lib.sh lib/ctrl.lib.sh lib/cache.lib.sh lib/zbxapi.lib.sh lib/JSON.sh README.md; do zaf_install $i ${ZAF_LIB_DIR}/ || zaf_err "Error installing $i" From 2d9c2059fe79d370d478a4acc59bc2933fed8eee Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 21 Apr 2016 15:59:29 +0200 Subject: [PATCH 21/32] Cache now predelete content due to rights mistake --- lib/cache.lib.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 9a7c985..8b2ea2b 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -30,6 +30,7 @@ zaf_tocache(){ local expiry key=$(zaf_cache_key "$1") + rm -f $ZAF_CACHE_DIR/$key $ZAF_CACHE_DIR/${key}.info echo "$2" >$ZAF_CACHE_DIR/$key echo "$1" >$ZAF_CACHE_DIR/${key}.info expiry=$(zaf_date_add "$3") @@ -46,6 +47,7 @@ zaf_tocache_stdin(){ local expiry key=$(zaf_cache_key "$1") + rm -f $ZAF_CACHE_DIR/$key $ZAF_CACHE_DIR/${key}.info cat >$ZAF_CACHE_DIR/$key if [ -s $ZAF_CACHE_DIR/$key ]; then expiry="$(zaf_date_add $2)" From 1ea7d93cd850e931f233c3b66641b592ed0005ff Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 21 Apr 2016 16:07:21 +0200 Subject: [PATCH 22/32] Right permissions on cache --- lib/cache.lib.sh | 2 +- zaf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 8b2ea2b..663138d 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -10,7 +10,7 @@ zaf_cache_clean(){ mkdir -p "$ZAF_CACHE_DIR" if zaf_is_root; then chmod 770 "$ZAF_CACHE_DIR" - chgrp zabbix "$ZAF_CACHE_DIR" + chgrp $(id -g zabbix) "$ZAF_CACHE_DIR" fi } diff --git a/zaf b/zaf index d8745f3..a389fda 100755 --- a/zaf +++ b/zaf @@ -64,8 +64,8 @@ if ! [ -d "${ZAF_CACHE_DIR}" ]; then fi if zaf_is_root; then - chgrp zabbix "${ZAF_CACHE_DIR}" - chmod g+w "${ZAF_CACHE_DIR}" + chgrp $(id -g zabbix) "${ZAF_CACHE_DIR}" + chmod 770 "${ZAF_CACHE_DIR}" fi case $1 in From efd52abc62ca63a0f763e0e39a7bd845c23b8797 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Fri, 22 Apr 2016 08:38:36 +0200 Subject: [PATCH 23/32] Repaired show plugin --- lib/plugin.lib.sh | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/plugin.lib.sh b/lib/plugin.lib.sh index 90ad655..3554cfd 100644 --- a/lib/plugin.lib.sh +++ b/lib/plugin.lib.sh @@ -197,23 +197,29 @@ zaf_list_plugin_items() { 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 - if [ -n "$testparms" ] && [ "$2" = "test" ]; then - for tp in $testparms; do + case $2 in + test) + for tp in $testparms; do + if [ -n "$p" ]; then echo -n "$1.$i[$tp] " - done - else - if [ -n "$precache" ] && [ "$2" = "precache" ]; then - for tp in $precache; do - echo -n "$1.$i[$tp] " - done + else + echo -n "$1.$i " fi - [ "$2" != "test" ] && key="$1.$i[]" + done + ;; + precache) + for tp in $precache; do + echo -n "$1.$i[$tp] " + done + ;; + *) + if [ -n "$p" ]; then + echo -n "$1.$i[] " + else + echo -n "$1.$i " fi - else - key="$1.$i" - fi - [ "$2" != "precache" ] && echo -n "$key " + ;; + esac done echo } From 2bb33dc105a9fff4f50fa01ad562e0a84eff6aee Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Fri, 22 Apr 2016 09:44:38 +0200 Subject: [PATCH 24/32] Force preloading of env before script execution Parameters are exported as variables --- lib/ctrl.lib.sh | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 3790e8e..0604ab9 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -209,13 +209,14 @@ zaf_ctrl_generate_cfg() { args="" apos=1; while read pname pdefault pregex prest; do - zafparams="$zafparams value=\"\$$apos\"; zaf_agentparm $pname $pdefault $pregex;" + zafparams="$zafparams value=\"\$$apos\"; zaf_agentparm $pname $pdefault $pregex; export $pname; " args="$args \$$apos" apos=$(expr $apos + 1) done <$tmpfile else ikey="$2.$i" fi + env="export ITEM_KEY='$ikey'; export PATH=${ZAF_PLUGINS_DIR}/$2:$ZAF_LIB_DIR:\$PATH; cd ${ZAF_PLUGINS_DIR}/$2; . $ZAF_LIB_DIR/preload.sh; " lock=$(zaf_ctrl_get_item_option $1 $i "Lock") if [ -n "$lock" ]; then lock="${ZAF_LIB_DIR}/zaflock $lock " @@ -225,24 +226,18 @@ zaf_ctrl_generate_cfg() { cache="${ZAF_LIB_DIR}/zafcache '$cache' " fi cmd=$(zaf_ctrl_get_item_option $1 $i "Cmd") - if [ -z "$cache" ] && [ -z "$lock" ]; then - preload="${ZAF_LIB_DIR}/preload.sh " - else - preload="" - fi if [ -n "$cmd" ]; then - printf "%s" "UserParameter=$ikey,export ITEM_KEY='$ikey'; ${preload}${cache}${lock}${cmd}"; echo + printf "%s" "UserParameter=$ikey,${env}${zafparams}${preload}${cache}${lock}${cmd} ${args}"; echo continue fi cmd=$(zaf_ctrl_get_item_option $1 $i "Script") if [ -n "$cmd" ]; then ( echo "#!/bin/sh" echo ". $ZAF_LIB_DIR/preload.sh; " - echo "$zafparams" zaf_ctrl_get_item_option $1 $i "Script" ) >${ZAF_TMP_DIR}/${iscript}.sh; [ -z "$3" ] && zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ - printf "%s" "UserParameter=$ikey,export ITEM_KEY='$ikey'; ${preload}${cache}${lock}${ZAF_PLUGINS_DIR}/$2/${iscript}.sh $args"; echo + printf "%s" "UserParameter=$ikey,${env}${preload}${zafparams}${cache}${lock}${ZAF_PLUGINS_DIR}/$2/${iscript}.sh ${args}"; echo continue; fi zaf_err "Item $i declared in control file but has no Cmd, Function or Script!" From b18919362a4334cc101fbbd65fbae1366446bef0 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Sun, 24 Apr 2016 04:51:35 +0200 Subject: [PATCH 25/32] Repaired files and modes Repaired init functions --- install.sh | 107 +++++++++++++++++++++++------------------------ lib/cache.lib.sh | 31 +++++++++++--- lib/os.lib.sh | 3 ++ lib/preload.sh | 25 +++-------- lib/zaf.lib.sh | 23 ++++++++++ zaf | 27 ++---------- 6 files changed, 114 insertions(+), 102 deletions(-) diff --git a/install.sh b/install.sh index 8ac9725..74384c1 100755 --- a/install.sh +++ b/install.sh @@ -1,17 +1,6 @@ #!/bin/sh -[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 -export ZAF_LOG_STDERR="-s" -if [ -z "$ZAF_URL" ]; then - # Runing as standalone install.sh. We have to download rest of files first. - ZAF_URL="https://github.com/limosek/zaf/" -fi - -[ -z "$ZAF_GITBRANCH" ] && ZAF_GITBRANCH=1.2 - -ZAF_TMP_DIR="/tmp/zaf-installer" -ZAF_DIR="$ZAF_TMP_DIR/zaf" -mkdir -p $ZAF_TMP_DIR +############### Functions # Lite version of zaf_fetch_url, full version will be loaded later zaf_fetch_url(){ @@ -33,40 +22,6 @@ zaf_download_files() { zaf_fetch_url $ZAF_URL/archive/$ZAF_GITBRANCH.tar.gz | tar -f - -C $ZAF_TMP_DIR -zx && mv $ZAF_TMP_DIR/zaf-$ZAF_GITBRANCH $ZAF_DIR || zaf_err "Cannot download and unpack zaf!" } -if ! [ -f README.md ]; then - # We are runing from stdin - if ! which curl >/dev/null; - then - zaf_err "Curl not found. Cannot continue. Please install it." - fi - echo "Installing from url $url..." - [ -z "$*" ] && auto=auto - zaf_download_files && cd $ZAF_DIR && exec ./install.sh $auto "$@" - echo "Error downloading and runing installer!" >&2 - exit 2 -fi - -if ! type zaf_version >/dev/null; then -. lib/zaf.lib.sh -. lib/plugin.lib.sh -. lib/os.lib.sh -. lib/ctrl.lib.sh -. lib/cache.lib.sh -. lib/zbxapi.lib.sh -fi - -# Read options as config for ZAF -for pair in "$@"; do - echo $pair | grep -q '^ZAF\_' || continue - option=$(echo $pair|cut -d '=' -f 1) - value=$(echo $pair|cut -d '=' -f 2-) - eval "C_${option}='$value'" - zaf_wrn "Overriding $option from cmdline." -done - -[ -z "$ZAF_CFG_FILE" ] && ZAF_CFG_FILE=$INSTALL_PREFIX/etc/zaf.conf -[ -n "$C_ZAF_DEBUG" ] && ZAF_DEBUG=$C_ZAF_DEBUG - # Read option. If it is already set in zaf.conf, it is skipped. If env variable is set, it is used instead of default # It sets global variable name on result. # $1 - option name @@ -269,6 +224,9 @@ zaf_configure(){ zaf_set_option ZAF_AGENT_CONFIG "$ZAF_AGENT_CONFIG" zaf_set_option ZAF_AGENT_CONFIGD "$ZAF_AGENT_CONFIGD" zaf_set_option ZAF_AGENT_BIN "$ZAF_AGENT_BIN" + zaf_set_option ZAF_FILES_UID "$ZAF_FILES_UID" + zaf_set_option ZAF_FILES_GID "$ZAF_FILES_GID" + zaf_set_option ZAF_FILES_UMASK "$ZAF_FILES_UMASK" zaf_set_option ZAF_AGENT_RESTART "$ZAF_AGENT_RESTART" zaf_set_option ZAF_SUDOERSD "$ZAF_SUDOERSD" zaf_set_option ZAF_CROND "$ZAF_CROND" @@ -321,18 +279,59 @@ zaf_postconfigure() { true } +############ First stage Init + +if ! [ -f README.md ]; then + # We are runing from stdin + if ! which curl >/dev/null; + then + zaf_err "Curl not found. Cannot continue. Please install it." + fi + echo "Installing from url $url..." + [ -z "$*" ] && auto=auto + zaf_download_files && cd $ZAF_DIR && exec ./install.sh $auto "$@" + echo "Error downloading and runing installer!" >&2 + exit 2 +fi + +# Try to load local downloaded libs +if ! type zaf_version >/dev/null; then +. lib/zaf.lib.sh +. lib/plugin.lib.sh +. lib/os.lib.sh +. lib/ctrl.lib.sh +. lib/cache.lib.sh +. lib/zbxapi.lib.sh +fi +# If something was wrong reading libs, then exit +if ! type zaf_version >/dev/null; then + echo "Problem loading libraries?" + exit 2 +fi + +########### Second stage init (all functions loaded) + +[ -z "$ZAF_CFG_FILE" ] && ZAF_CFG_FILE=$INSTALL_PREFIX/etc/zaf.conf if [ -f "${ZAF_CFG_FILE}" ]; then . "${ZAF_CFG_FILE}" fi -ZAF_TMP_DIR="/tmp/zaf-installer/" -! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" -# If debug is on, do not remove tmp dir -if [ "$ZAF_DEBUG" -le 3 ]; then - trap "rm -rf ${ZAF_TMP_DIR} " EXIT -else - trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT -fi +zaf_debug_init stderr + +ZAF_TMP_DIR="/tmp/zaf-installer" +ZAF_DIR="$ZAF_TMP_DIR/zaf" +zaf_tmp_init + +zaf_cache_init + +# Read options as config for ZAF +for pair in "$@"; do + echo $pair | grep -q '^ZAF\_' || continue + option=$(echo $pair|cut -d '=' -f 1) + value=$(echo $pair|cut -d '=' -f 2-) + eval "C_${option}='$value'" + zaf_wrn "Overriding $option from cmdline." +done case $1 in interactive) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 663138d..95a64b0 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -1,5 +1,30 @@ # Zaf cache related functions +zaf_cache_init(){ + [ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c + if [ -n "$ZAF_CACHE_DIR" ]; then + mkdir -p "$ZAF_CACHE_DIR" + if zaf_is_root; then + zaf_trc "Cache: Changing perms to $ZAF_CACHE_DIR (zabbix/$ZAF_ZABBIX_GID/0770)" + chown $ZAF_FILES_UID "$ZAF_CACHE_DIR" + chgrp $ZAF_FILES_GID "$ZAF_CACHE_DIR" + chmod $ZAF_FILES_UMASK "$ZAF_CACHE_DIR" + fi + if [ -w $ZAF_CACHE_DIR ]; then + zaf_trc "Cache: Removing stale entries" + (cd $ZAF_CACHE_DIR && find ./ -type f -name '*.info' -mmin +1 | \ + while read line ; do + echo rm -f $line $(basename $line .info) + done + ) + else + zaf_err "Cache dir is not accessible! Become root or member of $ZAF_FILES_GID group!" + fi + else + zaf_err "Cache dir not set." + fi +} + zaf_cache_clean(){ if [ -n "$ZAF_CACHE_DIR" ]; then zaf_wrn "Removing cache entries" @@ -7,11 +32,7 @@ zaf_cache_clean(){ else zaf_err "Cache dir not set." fi - mkdir -p "$ZAF_CACHE_DIR" - if zaf_is_root; then - chmod 770 "$ZAF_CACHE_DIR" - chgrp $(id -g zabbix) "$ZAF_CACHE_DIR" - fi + zaf_cache_init } # Get cache key from requested param diff --git a/lib/os.lib.sh b/lib/os.lib.sh index d10ed66..d3e320c 100644 --- a/lib/os.lib.sh +++ b/lib/os.lib.sh @@ -21,6 +21,9 @@ zaf_configure_os_freebsd() { } zaf_detect_system() { + ZAF_FILES_UID=zabbix + ZAF_FILES_GID=zabbix + ZAF_FILES_UMASK=0770 if which dpkg >/dev/null; then ZAF_PKG=dpkg ZAF_OS=$(lsb_release -is|zaf_tolower) diff --git a/lib/preload.sh b/lib/preload.sh index d638215..cbd9795 100644 --- a/lib/preload.sh +++ b/lib/preload.sh @@ -9,26 +9,13 @@ . ${ZAF_LIB_DIR}/zbxapi.lib.sh . ${ZAF_LIB_DIR}/cache.lib.sh -[ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf -[ -z "$ZAF_TMP_DIR" ] && ZAF_TMP_DIR="${ZAF_TMP_BASE}-$(zaf_random)" -[ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c - -rm -rf "${ZAF_TMP_DIR}" - -if ! [ -d "${ZAF_TMP_DIR}" ]; then - mkdir "${ZAF_TMP_DIR}" +if ! type zaf_version >/dev/null; then + echo "Problem loading libraries?" + exit 2 fi - -! [ -d "${ZAF_CACHE_DIR}" ] && mkdir "${ZAF_CACHE_DIR}" -[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 - -if [ "$ZAF_DEBUG" -le 3 ]; then - trap "rm -rf ${ZAF_TMP_DIR}" EXIT -else - trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT -fi - -#trap 'touch /tmp/aaaa' ALARM +zaf_debug_init +zaf_tmp_init +zaf_cache_init export ZAF_LIB_DIR export ZAF_TMP_DIR diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 19566db..43f536d 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -38,6 +38,12 @@ zaf_hlp() { dl=$(expr $cols - $kl) printf %-${kl}s%-${dl}s%b "$1" "$2" "\n" } +# $1 if nonempty, log to stderr too +zaf_debug_init() { + [ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 + export ZAF_DEBUG + [ -n "$1" ] && export ZAF_LOG_STDERR="-s" +} zaf_version(){ echo $ZAF_VERSION @@ -236,6 +242,23 @@ zaf_date_add() { date -d "$1 seconds" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -d "$(expr $(date +%s) + $1)" -D %s "+%Y-%m-%d %H:%M:%S" } +zaf_tmp_init() { + [ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf + ZAF_TMP_DIR="${ZAF_TMP_BASE}-$(zaf_random)" + mkdir -p $ZAF_TMP_DIR + if zaf_is_root; then + chown $ZAF_FILES_UID "$ZAF_TMP_DIR" + chgrp $ZAF_FILES_GID "$ZAF_TMP_DIR" + chmod $ZAF_FILES_UMASK "$ZAF_TMP_DIR" + fi + # If debug is on, do not remove tmp dir + if [ "$ZAF_DEBUG" -le 3 ]; then + trap "rm -rf ${ZAF_TMP_DIR}" EXIT + else + trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT + fi +} + # Create temp file and return its name # $1 prefix or empty zaf_tmpfile() { diff --git a/zaf b/zaf index a389fda..cf376ba 100755 --- a/zaf +++ b/zaf @@ -43,30 +43,9 @@ else [ -f ${ZAF_LIB_DIR}/zaf.${ZAF_OS}.sh ] && . ${ZAF_LIB_DIR}/zaf.${ZAF_OS}.sh fi -[ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf -ZAF_TMP_DIR="${ZAF_TMP_BASE}-$(zaf_random)" -[ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c - -[ -z "$ZAF_DEBUG" ] && ZAF_DEBUG=1 -export ZAF_DEBUG -export ZAF_LOG_STDERR="-s" - -# If debug is on, do not remove tmp dir -if [ "$ZAF_DEBUG" -le 3 ]; then - trap "rm -rf ${ZAF_TMP_DIR}" EXIT -else - trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT -fi - -! [ -d "${ZAF_TMP_DIR}" ] && mkdir "${ZAF_TMP_DIR}" -if ! [ -d "${ZAF_CACHE_DIR}" ]; then - mkdir "${ZAF_CACHE_DIR}" -fi - -if zaf_is_root; then - chgrp $(id -g zabbix) "${ZAF_CACHE_DIR}" - chmod 770 "${ZAF_CACHE_DIR}" -fi +zaf_debug_init stderr +zaf_tmp_init +zaf_cache_init case $1 in From f5b88cc4d983347eea73d65a7bab9491aa1c1e32 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Sun, 24 Apr 2016 04:59:23 +0200 Subject: [PATCH 26/32] Reorganized stage1 init --- install.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/install.sh b/install.sh index 74384c1..92a7e14 100755 --- a/install.sh +++ b/install.sh @@ -282,7 +282,14 @@ zaf_postconfigure() { ############ First stage Init if ! [ -f README.md ]; then - # We are runing from stdin + # Hardcoded variables + ZAF_VERSION="1.2" + ZAF_GITBRANCH="1.2" + ZAF_URL="https://github.com/limosek/zaf" + ZAF_RAW_URL="https://raw.githubusercontent.com/limosek/zaf" + export ZAF_TMP_DIR="/tmp/zaf-installer" + export ZAF_DIR="$ZAF_TMP_DIR/zaf" + mkdir -p $ZAF_TMP_DIR if ! which curl >/dev/null; then zaf_err "Curl not found. Cannot continue. Please install it." @@ -315,13 +322,11 @@ fi if [ -f "${ZAF_CFG_FILE}" ]; then . "${ZAF_CFG_FILE}" fi +export ZAF_TMP_DIR="/tmp/zaf-installer" +export ZAF_DIR="$ZAF_TMP_DIR/zaf" zaf_debug_init stderr - -ZAF_TMP_DIR="/tmp/zaf-installer" -ZAF_DIR="$ZAF_TMP_DIR/zaf" zaf_tmp_init - zaf_cache_init # Read options as config for ZAF From 276aef1689b08a3a3449eda83cecfacdb7d3bb19 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Sun, 24 Apr 2016 05:23:32 +0200 Subject: [PATCH 27/32] Removing files echo delete --- lib/cache.lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 95a64b0..3de1fa6 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -14,7 +14,7 @@ zaf_cache_init(){ zaf_trc "Cache: Removing stale entries" (cd $ZAF_CACHE_DIR && find ./ -type f -name '*.info' -mmin +1 | \ while read line ; do - echo rm -f $line $(basename $line .info) + rm -f $line $(basename $line .info) done ) else From 7af97e2a13043188b32c5d7cd7c78f13c9709be1 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Sun, 24 Apr 2016 05:31:51 +0200 Subject: [PATCH 28/32] Missed vatiable emptying on item create --- lib/ctrl.lib.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 0604ab9..e65d508 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -215,6 +215,8 @@ zaf_ctrl_generate_cfg() { done <$tmpfile else ikey="$2.$i" + zafparams="" + args="" fi env="export ITEM_KEY='$ikey'; export PATH=${ZAF_PLUGINS_DIR}/$2:$ZAF_LIB_DIR:\$PATH; cd ${ZAF_PLUGINS_DIR}/$2; . $ZAF_LIB_DIR/preload.sh; " lock=$(zaf_ctrl_get_item_option $1 $i "Lock") From 4bdeaf9f9a6248da601c3114b16d7192c4ba4f49 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Thu, 28 Apr 2016 14:24:16 +0200 Subject: [PATCH 29/32] Args have to be set in control file for Cmd --- lib/ctrl.lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index e65d508..256dfff 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -229,7 +229,7 @@ zaf_ctrl_generate_cfg() { fi cmd=$(zaf_ctrl_get_item_option $1 $i "Cmd") if [ -n "$cmd" ]; then - printf "%s" "UserParameter=$ikey,${env}${zafparams}${preload}${cache}${lock}${cmd} ${args}"; echo + printf "%s" "UserParameter=$ikey,${env}${zafparams}${preload}${cache}${lock}${cmd}"; echo continue fi cmd=$(zaf_ctrl_get_item_option $1 $i "Script") From ca4f170ca3ba96f944a47f5bdc1db43fb1690b83 Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Wed, 4 May 2016 16:09:34 +0200 Subject: [PATCH 30/32] Repaired tmp and cache directory init and clean --- install.sh | 19 ++++++++++++++++--- lib/cache.lib.sh | 37 +++++++++++++++---------------------- lib/plugin.lib.sh | 16 +++++++++++----- lib/zaf.lib.sh | 22 +++++----------------- 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/install.sh b/install.sh index 92a7e14..9102805 100755 --- a/install.sh +++ b/install.sh @@ -180,7 +180,8 @@ zaf_configure(){ fi zaf_get_option ZAF_GIT "Git is installed" "$ZAF_GIT" "$INSTALL_MODE" zaf_get_option ZAF_CURL_INSECURE "Insecure curl (accept all certificates)" "1" "$INSTALL_MODE" - zaf_get_option ZAF_TMP_BASE "Tmp directory prefix (\$USER will be added)" "/tmp/zaf" "$INSTALL_MODE" + zaf_get_option ZAF_TMP_DIR "Tmp directory" "/tmp/" "$INSTALL_MODE" + zaf_get_option ZAF_CACHE_DIR "Cache directory" "/tmp/zafc" "$INSTALL_MODE" zaf_get_option ZAF_LIB_DIR "Libraries directory" "/usr/lib/zaf" "$INSTALL_MODE" zaf_get_option ZAF_BIN_DIR "Directory to put binaries" "/usr/bin" "$INSTALL_MODE" zaf_get_option ZAF_PLUGINS_DIR "Plugins directory" "${ZAF_LIB_DIR}/plugins" "$INSTALL_MODE" @@ -214,7 +215,8 @@ zaf_configure(){ zaf_set_option ZAF_AGENT_PKG "${ZAF_AGENT_PKG}" zaf_set_option ZAF_GIT "${ZAF_GIT}" zaf_set_option ZAF_CURL_INSECURE "${ZAF_CURL_INSECURE}" - zaf_set_option ZAF_TMP_BASE "$ZAF_TMP_BASE" + zaf_set_option ZAF_TMP_DIR "$ZAF_TMP_DIR" + zaf_set_option ZAF_CACHE_DIR "$ZAF_CACHE_DIR" zaf_set_option ZAF_LIB_DIR "$ZAF_LIB_DIR" zaf_set_option ZAF_BIN_DIR "$ZAF_BIN_DIR" zaf_set_option ZAF_PLUGINS_DIR "$ZAF_PLUGINS_DIR" @@ -240,6 +242,17 @@ zaf_configure(){ zaf_configure_agent $ZAF_AGENT_OPTIONS "$@" zaf_add_agent_option "Include" "$ZAF_AGENT_CONFIGD" fi + + if ! [ -d $ZAF_CACHE_DIR ]; then + mkdir -p "$ZAF_CACHE_DIR" + if zaf_is_root && [ -n "$ZAF_FILES_UID" ] && [ -n "$ZAF_FILES_GID" ]; then + zaf_wrn "Cache: Changing perms to $ZAF_CACHE_DIR (zabbix/$ZAF_ZABBIX_GID/0770)" + chown $ZAF_FILES_UID "$ZAF_CACHE_DIR" + chgrp $ZAF_FILES_GID "$ZAF_CACHE_DIR" + chmod $ZAF_FILES_UMASK "$ZAF_CACHE_DIR" + fi + fi + zaf_cache_init } zaf_install_all() { @@ -327,7 +340,6 @@ export ZAF_DIR="$ZAF_TMP_DIR/zaf" zaf_debug_init stderr zaf_tmp_init -zaf_cache_init # Read options as config for ZAF for pair in "$@"; do @@ -337,6 +349,7 @@ for pair in "$@"; do eval "C_${option}='$value'" zaf_wrn "Overriding $option from cmdline." done +[ -z "$C_ZAF_TMP_DIR" ] && C_ZAF_TMP_DIR="/tmp/" case $1 in interactive) diff --git a/lib/cache.lib.sh b/lib/cache.lib.sh index 3de1fa6..5156d6e 100644 --- a/lib/cache.lib.sh +++ b/lib/cache.lib.sh @@ -1,36 +1,29 @@ # Zaf cache related functions zaf_cache_init(){ - [ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_BASE}c - if [ -n "$ZAF_CACHE_DIR" ]; then - mkdir -p "$ZAF_CACHE_DIR" - if zaf_is_root; then - zaf_trc "Cache: Changing perms to $ZAF_CACHE_DIR (zabbix/$ZAF_ZABBIX_GID/0770)" - chown $ZAF_FILES_UID "$ZAF_CACHE_DIR" - chgrp $ZAF_FILES_GID "$ZAF_CACHE_DIR" - chmod $ZAF_FILES_UMASK "$ZAF_CACHE_DIR" - fi - if [ -w $ZAF_CACHE_DIR ]; then - zaf_trc "Cache: Removing stale entries" - (cd $ZAF_CACHE_DIR && find ./ -type f -name '*.info' -mmin +1 | \ - while read line ; do - rm -f $line $(basename $line .info) - done - ) - else - zaf_err "Cache dir is not accessible! Become root or member of $ZAF_FILES_GID group!" - fi + [ -z "$ZAF_CACHE_DIR" ] && ZAF_CACHE_DIR=${ZAF_TMP_DIR}/zafc + if [ -w $ZAF_CACHE_DIR ]; then + zaf_trc "Cache: Removing stale entries" + (cd $ZAF_CACHE_DIR && find ./ -type f -name '*.info' -mmin +1 2>/dev/null | \ + while read line ; do + rm -f $line $(basename $line .info) + done + ) else - zaf_err "Cache dir not set." + zaf_dbg "Cache dir $ZAF_CACHE_DIR is not accessible! Disabling cache." fi } zaf_cache_clean(){ if [ -n "$ZAF_CACHE_DIR" ]; then zaf_wrn "Removing cache entries" - rm -rf "$ZAF_CACHE_DIR" + (cd $ZAF_CACHE_DIR && find ./ -type f -name '*.info' 2>/dev/null | \ + while read line ; do + rm -f $line $(basename $line .info) + done + ) else - zaf_err "Cache dir not set." + zaf_dbg "Cache dir not set. Disabling cache." fi zaf_cache_init } diff --git a/lib/plugin.lib.sh b/lib/plugin.lib.sh index 3554cfd..362bc2a 100644 --- a/lib/plugin.lib.sh +++ b/lib/plugin.lib.sh @@ -45,6 +45,7 @@ zaf_get_plugin_url() { # $1 - control zaf_plugin_info() { local control="$1" + local items ! [ -f "$control" ] && zaf_err "Control file $control not found." plugin=$(zaf_ctrl_get_global_block <"${control}" | zaf_block_get_option Plugin) @@ -62,9 +63,12 @@ zaf_plugin_info() { [ -n "$phome" ] && echo "Home: $phome" 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 + items=$(zaf_list_plugin_items $plugin) + [ -n "$items" ] && echo -n "Defined items: "; echo $items + items=$(zaf_list_plugin_items $plugin test) + [ -n "$items" ] && echo -n "Test items: "; echo $items + items=$(zaf_list_plugin_items $plugin precache) + [ -n "$items" ] && echo -n "Precache items: "; echo $items else echo "Items: $pitems" fi @@ -227,6 +231,7 @@ zaf_list_plugin_items() { zaf_item_info() { local plugin local item + local param plugin=$(echo $1 | cut -d '.' -f 1) item=$(echo $1 | cut -d '.' -f 2-) @@ -237,9 +242,10 @@ zaf_item_info() { echo "Parameters:" zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Parameters" ; echo echo "Testparameters:" - zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Testparameters" ; echo + zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Testparameters"; echo echo "Precache:" - zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Precache" ; echo + zaf_ctrl_get_item_option $ZAF_PLUGINS_DIR/$plugin/control.zaf "$item" "Precache"; echo + grep "UserParameter=$1" $ZAF_AGENT_CONFIGD/zaf_${plugin}.conf else zaf_err "No such item $item." fi diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 43f536d..8f8ac15 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -45,6 +45,11 @@ zaf_debug_init() { [ -n "$1" ] && export ZAF_LOG_STDERR="-s" } +zaf_tmp_init() { + [ -z "$ZAF_TMP_DIR" ] && ZAF_TMP_DIR=/tmp/ + ! [ -w "$ZAF_TMP_DIR" ] && zaf_err "Tmp dir $ZAF_TMP_DIR is not writable." +} + zaf_version(){ echo $ZAF_VERSION } @@ -242,23 +247,6 @@ zaf_date_add() { date -d "$1 seconds" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -d "$(expr $(date +%s) + $1)" -D %s "+%Y-%m-%d %H:%M:%S" } -zaf_tmp_init() { - [ -z "$ZAF_TMP_BASE" ] && ZAF_TMP_BASE=/tmp/zaf - ZAF_TMP_DIR="${ZAF_TMP_BASE}-$(zaf_random)" - mkdir -p $ZAF_TMP_DIR - if zaf_is_root; then - chown $ZAF_FILES_UID "$ZAF_TMP_DIR" - chgrp $ZAF_FILES_GID "$ZAF_TMP_DIR" - chmod $ZAF_FILES_UMASK "$ZAF_TMP_DIR" - fi - # If debug is on, do not remove tmp dir - if [ "$ZAF_DEBUG" -le 3 ]; then - trap "rm -rf ${ZAF_TMP_DIR}" EXIT - else - trap 'zaf_wrn "Leaving $ZAF_TMP_DIR" contents due to ZAF_DEBUG.' EXIT - fi -} - # Create temp file and return its name # $1 prefix or empty zaf_tmpfile() { From 658496e7ccc71c9b333ebb07627bf98fd0c929ba Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Wed, 4 May 2016 16:20:23 +0200 Subject: [PATCH 31/32] Temp file auto deletion --- lib/ctrl.lib.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 256dfff..306c322 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -240,11 +240,13 @@ zaf_ctrl_generate_cfg() { ) >${ZAF_TMP_DIR}/${iscript}.sh; [ -z "$3" ] && zaf_install_bin ${ZAF_TMP_DIR}/${iscript}.sh ${ZAF_PLUGINS_DIR}/$2/ printf "%s" "UserParameter=$ikey,${env}${preload}${zafparams}${cache}${lock}${ZAF_PLUGINS_DIR}/$2/${iscript}.sh ${args}"; echo + rm -f ${ZAF_TMP_DIR}/${iscript}.sh 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" + rm -f $tmpfile } From 7b07643be9d5f767d5d216d899e1fbbcc08d56eb Mon Sep 17 00:00:00 2001 From: Lukas Macura Date: Fri, 13 May 2016 18:00:19 +0200 Subject: [PATCH 32/32] Simulate zaf_sudo if needed Add plugin name as env var --- install.sh | 1 + lib/ctrl.lib.sh | 2 +- lib/preload.sh | 5 ++++- lib/zaf.lib.sh | 9 +++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 9102805..942282c 100755 --- a/install.sh +++ b/install.sh @@ -338,6 +338,7 @@ fi export ZAF_TMP_DIR="/tmp/zaf-installer" export ZAF_DIR="$ZAF_TMP_DIR/zaf" +! [ -d $ZAF_TMP_DIR ] && mkdir -p $ZAF_TMP_DIR zaf_debug_init stderr zaf_tmp_init diff --git a/lib/ctrl.lib.sh b/lib/ctrl.lib.sh index 306c322..e84262a 100644 --- a/lib/ctrl.lib.sh +++ b/lib/ctrl.lib.sh @@ -218,7 +218,7 @@ zaf_ctrl_generate_cfg() { zafparams="" args="" fi - env="export ITEM_KEY='$ikey'; export PATH=${ZAF_PLUGINS_DIR}/$2:$ZAF_LIB_DIR:\$PATH; cd ${ZAF_PLUGINS_DIR}/$2; . $ZAF_LIB_DIR/preload.sh; " + env="export ITEM_KEY='$ikey'; export PLUGIN='$2'; export PATH=${ZAF_PLUGINS_DIR}/$2:$ZAF_LIB_DIR:\$PATH; cd ${ZAF_PLUGINS_DIR}/$2; . $ZAF_LIB_DIR/preload.sh; " lock=$(zaf_ctrl_get_item_option $1 $i "Lock") if [ -n "$lock" ]; then lock="${ZAF_LIB_DIR}/zaflock $lock " diff --git a/lib/preload.sh b/lib/preload.sh index cbd9795..2822c16 100644 --- a/lib/preload.sh +++ b/lib/preload.sh @@ -9,6 +9,9 @@ . ${ZAF_LIB_DIR}/zbxapi.lib.sh . ${ZAF_LIB_DIR}/cache.lib.sh +# Plugin specific functions if exists +[ -f ./functions.sh ] && . ./functions.sh + if ! type zaf_version >/dev/null; then echo "Problem loading libraries?" exit 2 @@ -23,7 +26,7 @@ export ZAF_CACHE_DIR export ZAF_PLUGINS_DIR export ZAF_DEBUG unset ZAF_LOG_STDERR -export PATH=$ZAF_LIB_DIR:$ZAF_BIN_DIR:$PATH +export PATH if [ "$(basename $0)" = "preload.sh" ] && [ -n "$*" ]; then tmpf=$(zaf_tmpfile preload) diff --git a/lib/zaf.lib.sh b/lib/zaf.lib.sh index 8f8ac15..562ce7e 100644 --- a/lib/zaf.lib.sh +++ b/lib/zaf.lib.sh @@ -258,3 +258,12 @@ zaf_random() { hexdump -n 2 -e '/2 "%u"' /dev/urandom } +# Emulate sudo +zaf_sudo() { + if zaf_is_root || ! which sudo >/dev/null 2>/dev/null; then + $@ + else + sudo $@ + fi +} +